Update branch

stix2.1
Emmanuelle Vargas-Gonzalez 2017-10-06 20:34:08 -04:00
commit 50f3d60259
64 changed files with 8788 additions and 347 deletions

1
.gitignore vendored
View File

@ -53,6 +53,7 @@ coverage.xml
# Sphinx documentation
docs/_build/
.ipynb_checkpoints
# PyBuilder
target/

View File

@ -1,6 +1,18 @@
CHANGELOG
=========
0.3.0 - 2017-10-06
* Adds data stores, object factory, and the environment layer.
* Supports pattern expressions and data markings.
* Fixes some bugs with timestamp precision and parsing of bundles.
* Includes support for custom object types, custom properties, custom observable
objects, and custom observable extensions.
0.2.0 - 2017-05-31
* Adds a TAXII data source.
0.1.0 - 2017-05-22
* Include support for serializing/deserializing all STIX objects and Cyber

View File

@ -28,11 +28,9 @@ Install with `pip <https://pip.pypa.io/en/stable/>`__:
Usage
-----
Creating STIX Domain Objects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To create a STIX object, provide keyword arguments to the type's
constructor:
constructor. Certain required attributes of all objects, such as ``type`` or
``id``, will be set automatically if not provided as keyword arguments.
.. code:: python
@ -42,147 +40,27 @@ constructor:
labels=["malicious-activity"],
pattern="[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']")
Certain required attributes of all objects will be set automatically if
not provided as keyword arguments:
- If not provided, ``type`` will be set automatically to the correct
type. You can also provide the type explicitly, but this is not
necessary:
To parse a STIX JSON string into a Python STIX object, use ``parse()``:
.. code:: python
indicator = Indicator(type='indicator', ...)
from stix2 import parse
Passing a value for ``type`` that does not match the class being
constructed will cause an error:
indicator = parse("""{
"type": "indicator",
"id": "indicator--dbcbd659-c927-4f9a-994f-0a2632274394",
"created": "2017-09-26T23:33:39.829Z",
"modified": "2017-09-26T23:33:39.829Z",
"labels": [
"malicious-activity"
],
"name": "File hash for malware variant",
"pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",
"valid_from": "2017-09-26T23:33:39.829952Z"
}""")
print(indicator)
.. code:: python
>>> indicator = Indicator(type='xxx', ...)
stix2.exceptions.InvalidValueError: Invalid value for Indicator 'type': must equal 'indicator'.
- If not provided, ``id`` will be generated randomly. If you provide an
``id`` argument, it must begin with the correct prefix:
.. code:: python
>>> indicator = Indicator(id="campaign--63ce9068-b5ab-47fa-a2cf-a602ea01f21a")
stix2.exceptions.InvalidValueError: Invalid value for Indicator 'id': must start with 'indicator--'.
- If not provided, ``created`` and ``modified`` will be set to the
(same) current time.
For indicators, ``labels`` and ``pattern`` are required and cannot be
set automatically. Trying to create an indicator that is missing one of
these properties will result in an error:
.. code:: python
>>> indicator = Indicator()
stix2.exceptions.MissingPropertiesError: No values for required properties for Indicator: (labels, pattern).
However, the required ``valid_from`` attribute on Indicators will be set
to the current time if not provided as a keyword argument.
Once created, the object acts like a frozen dictionary. Properties can
be accessed using the standard Python dictionary syntax:
.. code:: python
>>> indicator['name']
'File hash for malware variant'
TBD: Should we allow property access using the standard Python attribute
syntax?
.. code:: python
>>> indicator.name
'File hash for malware variant'
Attempting to modify any attributes will raise an error:
.. code:: python
>>> indicator['name'] = "This is a revised name"
TypeError: 'Indicator' object does not support item assignment
>>> indicator.name = "This is a revised name"
stix2.exceptions.ImmutableError: Cannot modify properties after creation.
To update the properties of an object, see `Versioning <#versioning>`__
below.
Creating a Malware object follows the same pattern:
.. code:: python
from stix2 import Malware
malware = Malware(name="Poison Ivy",
labels=['remote-access-trojan'])
As with indicators, the ``type``, ``id``, ``created``, and ``modified``
properties will be set automatically if not provided. For Malware
objects, the ``labels`` and ``name`` properties must be provided.
Creating Relationships
~~~~~~~~~~~~~~~~~~~~~~
STIX 2 Relationships are separate objects, not properties of the object
on either side of the relationship. They are constructed similarly to
other STIX objects. The ``type``, ``id``, ``created``, and ``modified``
properties are added automatically if not provided. Callers must provide
the ``relationship_type``, ``source_ref``, and ``target_ref``
properties.
.. code:: python
from stix2 import Relationship
relationship = Relationship(relationship_type='indicates',
source_ref=indicator.id,
target_ref=malware.id)
The ``source_ref`` and ``target_ref`` properties can be either the ID's
of other STIX objects, or the STIX objects themselves. For readability,
Relationship objects can also be constructed with the ``source_ref``,
``relationship_type``, and ``target_ref`` as positional (non-keyword)
arguments:
.. code:: python
relationship = Relationship(indicator, 'indicates', malware)
Creating Bundles
~~~~~~~~~~~~~~~~
STIX Bundles can be created by passing objects as arguments to the
Bundle constructor. All required properties (``type``, ``id``, and
``spec_version``) will be set automatically if not provided, or can be
provided as keyword arguments:
.. code:: python
from stix2 import bundle
bundle = Bundle(indicator, malware, relationship)
Serializing STIX objects
~~~~~~~~~~~~~~~~~~~~~~~~
The string representation of all STIX classes is a valid STIX JSON
object.
.. code:: python
indicator = Indicator(...)
print(str(indicator))
Versioning
~~~~~~~~~~
TBD
For more in-depth documentation, please see `https://stix2.readthedocs.io/ <https://stix2.readthedocs.io/>`__.
Governance
----------

View File

@ -0,0 +1,5 @@
{{ name }}
{{ underline }}
.. automodule:: {{ fullname }}
:members:

View File

@ -0,0 +1,5 @@
granular_markings
================================
.. automodule:: stix2.markings.granular_markings
:members:

View File

@ -0,0 +1,5 @@
object_markings
==============================
.. automodule:: stix2.markings.object_markings
:members:

View File

@ -0,0 +1,5 @@
utils
====================
.. automodule:: stix2.markings.utils
:members:

View File

@ -0,0 +1,5 @@
filesystem
========================
.. automodule:: stix2.sources.filesystem
:members:

View File

@ -0,0 +1,5 @@
filters
=====================
.. automodule:: stix2.sources.filters
:members:

View File

@ -0,0 +1,5 @@
memory
====================
.. automodule:: stix2.sources.memory
:members:

View File

@ -0,0 +1,5 @@
taxii
===================
.. automodule:: stix2.sources.taxii
:members:

View File

@ -0,0 +1,5 @@
common
============
.. automodule:: stix2.common
:members:

5
docs/api/stix2.core.rst Normal file
View File

@ -0,0 +1,5 @@
core
==========
.. automodule:: stix2.core
:members:

View File

@ -0,0 +1,5 @@
environment
=================
.. automodule:: stix2.environment
:members:

View File

@ -0,0 +1,5 @@
exceptions
================
.. automodule:: stix2.exceptions
:members:

View File

@ -0,0 +1,5 @@
markings
==============
.. automodule:: stix2.markings
:members:

View File

@ -0,0 +1,5 @@
observables
=================
.. automodule:: stix2.observables
:members:

View File

@ -0,0 +1,5 @@
patterns
==============
.. automodule:: stix2.patterns
:members:

View File

@ -0,0 +1,5 @@
properties
================
.. automodule:: stix2.properties
:members:

5
docs/api/stix2.sdo.rst Normal file
View File

@ -0,0 +1,5 @@
sdo
=========
.. automodule:: stix2.sdo
:members:

View File

@ -0,0 +1,5 @@
sources
=============
.. automodule:: stix2.sources
:members:

5
docs/api/stix2.sro.rst Normal file
View File

@ -0,0 +1,5 @@
sro
=========
.. automodule:: stix2.sro
:members:

5
docs/api/stix2.utils.rst Normal file
View File

@ -0,0 +1,5 @@
utils
===========
.. automodule:: stix2.utils
:members:

7
docs/api_ref.rst Normal file
View File

@ -0,0 +1,7 @@
API Reference
=============
This section of documentation contains information on all of the classes and
functions in the ``stix2`` API, as given by the package's docstrings.
.. automodule:: stix2

View File

@ -1,6 +1,25 @@
import os
import sys
sys.path.insert(0, os.path.abspath('..'))
extensions = [
'sphinx-prompt',
'nbsphinx',
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'sphinx.ext.napoleon',
'sphinx.ext.todo',
]
autodoc_default_flags = [
'undoc-members',
]
autodoc_member_order = 'groupwise'
autosummary_generate = True
napoleon_numpy_docstring = False # Force consistency, leave only Google
napoleon_use_rtype = False
add_module_names = False
templates_path = ['_templates']
source_suffix = '.rst'
master_doc = 'index'
@ -9,11 +28,11 @@ project = 'stix2'
copyright = '2017, OASIS Open'
author = 'OASIS Open'
version = '0.2.0'
release = '0.2.0'
version = '0.3.0'
release = '0.3.0'
language = None
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
exclude_patterns = ['_build', '_templates', 'Thumbs.db', '.DS_Store', 'guide/.ipynb_checkpoints']
pygments_style = 'sphinx'
todo_include_todos = False

7
docs/guide.rst Normal file
View File

@ -0,0 +1,7 @@
User's Guide
============
.. toctree::
:glob:
guide/*

891
docs/guide/creating.ipynb Normal file
View File

@ -0,0 +1,891 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true,
"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",
" 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": {
"collapsed": true,
"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\n",
"from pygments.formatters import HtmlFormatter\n",
"from IPython.display import HTML\n",
"\n",
"original_print = print\n",
"\n",
"def json_print(inpt):\n",
" string = str(inpt)\n",
" if string[0] == '{':\n",
" formatter = HtmlFormatter()\n",
" return HTML('<style type=\"text/css\">{}</style>{}'.format(\n",
" formatter.get_style_defs('.highlight'),\n",
" highlight(string, JsonLexer(), formatter)))\n",
" else:\n",
" original_print(inpt)\n",
"\n",
"print = json_print"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Creating STIX Content"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Creating STIX Domain Objects\n",
"\n",
"To create a STIX object, provide keyword arguments to the type's constructor:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.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;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--dbcbd659-c927-4f9a-994f-0a2632274394&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:33:39.829Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:33:39.829Z&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;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;File hash for malware variant&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;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:33:39.829952Z&quot;</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": [
"from stix2 import Indicator\n",
"\n",
"indicator = Indicator(name=\"File hash for malware variant\",\n",
" labels=[\"malicious-activity\"],\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")\n",
"print(indicator)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Certain required attributes of all objects will be set automatically if not provided as keyword arguments:\n",
"\n",
"- If not provided, ``type`` will be set automatically to the correct type. You can also provide the type explicitly, but this is not necessary:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"indicator2 = Indicator(type='indicator',\n",
" labels=[\"malicious-activity\"],\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Passing a value for ``type`` that does not match the class being constructed will cause an error:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"ename": "InvalidValueError",
"evalue": "Invalid value for Indicator 'type': must equal 'indicator'.",
"output_type": "error",
"traceback": [
"\u001b[0;31mInvalidValueError\u001b[0m\u001b[0;31m:\u001b[0m Invalid value for Indicator 'type': must equal 'indicator'.\n"
]
}
],
"source": [
"indicator3 = Indicator(type='xxx',\n",
" labels=[\"malicious-activity\"],\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- If not provided, ``id`` will be generated randomly. If you provide an\n",
" ``id`` argument, it must begin with the correct prefix:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"ename": "InvalidValueError",
"evalue": "Invalid value for Indicator 'id': must start with 'indicator--'.",
"output_type": "error",
"traceback": [
"\u001b[0;31mInvalidValueError\u001b[0m\u001b[0;31m:\u001b[0m Invalid value for Indicator 'id': must start with 'indicator--'.\n"
]
}
],
"source": [
"indicator4 = Indicator(id=\"campaign--63ce9068-b5ab-47fa-a2cf-a602ea01f21a\",\n",
" labels=[\"malicious-activity\"],\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For indicators, ``labels`` and ``pattern`` are required and cannot be set automatically. Trying to create an indicator that is missing one of these properties will result in an error:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"ename": "MissingPropertiesError",
"evalue": "No values for required properties for Indicator: (labels, pattern).",
"output_type": "error",
"traceback": [
"\u001b[0;31mMissingPropertiesError\u001b[0m\u001b[0;31m:\u001b[0m No values for required properties for Indicator: (labels, pattern).\n"
]
}
],
"source": [
"indicator = Indicator()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"However, the required ``valid_from`` attribute on Indicators will be set to the current time if not provided as a keyword argument.\n",
"\n",
"Once created, the object acts like a frozen dictionary. Properties can be accessed using the standard Python dictionary syntax:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"u'File hash for malware variant'"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"indicator['name']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Or access properties using the standard Python attribute syntax:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"u'File hash for malware variant'"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"indicator.name"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Attempting to modify any attributes will raise an error:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "'Indicator' object does not support item assignment",
"output_type": "error",
"traceback": [
"\u001b[0;31mTypeError\u001b[0m\u001b[0;31m:\u001b[0m 'Indicator' object does not support item assignment\n"
]
}
],
"source": [
"indicator['name'] = \"This is a revised name\""
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"ename": "ImmutableError",
"evalue": "Cannot modify 'name' property in 'Indicator' after creation.",
"output_type": "error",
"traceback": [
"\u001b[0;31mImmutableError\u001b[0m\u001b[0;31m:\u001b[0m Cannot modify 'name' property in 'Indicator' after creation.\n"
]
}
],
"source": [
"indicator.name = \"This is a revised name\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To update the properties of an object, see the **Versioning** section."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Creating a Malware object follows the same pattern:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.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;malware&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;malware--d7fd675d-94eb-4d95-b0bc-b3c5e28e8ed2&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:33:56.908Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:33:56.908Z&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;labels&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;remote-access-trojan&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": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from stix2 import Malware\n",
"\n",
"malware = Malware(name=\"Poison Ivy\",\n",
" labels=['remote-access-trojan'])\n",
"print(malware)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As with indicators, the ``type``, ``id``, ``created``, and ``modified`` properties will be set automatically if not provided. For Malware objects, the ``labels`` and ``name`` properties must be provided."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Creating Relationships\n",
"\n",
"STIX 2 Relationships are separate objects, not properties of the object on either side of the relationship. They are constructed similarly to other STIX objects. The ``type``, ``id``, ``created``, and ``modified`` properties are added automatically if not provided. Callers must provide the ``relationship_type``, ``source_ref``, and ``target_ref`` properties."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.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;relationship&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;relationship--637aa3b1-d4b8-4bc4-85e7-77cc82b198a3&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:34:01.765Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:34:01.765Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;relationship_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicates&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;source_ref&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--dbcbd659-c927-4f9a-994f-0a2632274394&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;target_ref&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;malware--d7fd675d-94eb-4d95-b0bc-b3c5e28e8ed2&quot;</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from stix2 import Relationship\n",
"\n",
"relationship = Relationship(relationship_type='indicates',\n",
" source_ref=indicator.id,\n",
" target_ref=malware.id)\n",
"print(relationship)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The ``source_ref`` and ``target_ref`` properties can be either the ID's of other STIX objects, or the STIX objects themselves. For readability, Relationship objects can also be constructed with the ``source_ref``, ``relationship_type``, and ``target_ref`` as positional (non-keyword) arguments:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.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;relationship&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;relationship--70fe77c2-ab00-4181-a2dc-fe5567d971ca&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:34:03.923Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:34:03.923Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;relationship_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicates&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;source_ref&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--dbcbd659-c927-4f9a-994f-0a2632274394&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;target_ref&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;malware--d7fd675d-94eb-4d95-b0bc-b3c5e28e8ed2&quot;</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"relationship2 = Relationship(indicator, 'indicates', malware)\n",
"print(relationship2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Creating Bundles\n",
"\n",
"STIX Bundles can be created by passing objects as arguments to the Bundle constructor. All required properties (``type``, ``id``, and ``spec_version``) will be set automatically if not provided, or can be provided as keyword arguments:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.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;bundle&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;bundle--2536c43d-c874-418e-886c-20a22120d8cb&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.0&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;objects&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <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;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--dbcbd659-c927-4f9a-994f-0a2632274394&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:33:39.829Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:33:39.829Z&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;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;File hash for malware variant&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;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:33:39.829952Z&quot;</span>\n",
" <span class=\"p\">},</span>\n",
" <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;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;malware--d7fd675d-94eb-4d95-b0bc-b3c5e28e8ed2&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:33:56.908Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:33:56.908Z&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;labels&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;remote-access-trojan&quot;</span>\n",
" <span class=\"p\">]</span>\n",
" <span class=\"p\">},</span>\n",
" <span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;relationship&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;relationship--637aa3b1-d4b8-4bc4-85e7-77cc82b198a3&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:34:01.765Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:34:01.765Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;relationship_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicates&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;source_ref&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--dbcbd659-c927-4f9a-994f-0a2632274394&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;target_ref&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;malware--d7fd675d-94eb-4d95-b0bc-b3c5e28e8ed2&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": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from stix2 import Bundle\n",
"\n",
"bundle = Bundle(indicator, malware, relationship)\n",
"print(bundle)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.12"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

938
docs/guide/custom.ipynb Normal file
View File

@ -0,0 +1,938 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true,
"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",
" 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": {
"collapsed": true,
"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\n",
"from pygments.formatters import HtmlFormatter\n",
"from IPython.display import HTML\n",
"\n",
"original_print = print\n",
"\n",
"def json_print(inpt):\n",
" string = str(inpt)\n",
" if string[0] == '{':\n",
" formatter = HtmlFormatter()\n",
" return HTML('<style type=\"text/css\">{}</style>{}'.format(\n",
" formatter.get_style_defs('.highlight'),\n",
" highlight(string, JsonLexer(), formatter)))\n",
" else:\n",
" original_print(inpt)\n",
"\n",
"print = json_print"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Custom STIX Content"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Custom Properties\n",
"\n",
"Attempting to create a STIX object with properties not defined by the specification will result in an error. Try creating an ``Identity`` object with a custom ``x_foo`` property:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"ename": "ExtraPropertiesError",
"evalue": "Unexpected properties for Identity: (x_foo).",
"output_type": "error",
"traceback": [
"\u001b[0;31mExtraPropertiesError\u001b[0m\u001b[0;31m:\u001b[0m Unexpected properties for Identity: (x_foo).\n"
]
}
],
"source": [
"from stix2 import Identity\n",
"\n",
"Identity(name=\"John Smith\",\n",
" identity_class=\"individual\",\n",
" x_foo=\"bar\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To create a STIX object with one or more custom properties, pass them in as a dictionary parameter called ``custom_properties``:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.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;x_foo&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;bar&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;identity&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;identity--8d7f0697-e589-4e3b-aa57-cae798d2d138&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T21:02:19.465Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T21:02:19.465Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;John Smith&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;identity_class&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;individual&quot;</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"identity = Identity(name=\"John Smith\",\n",
" identity_class=\"individual\",\n",
" custom_properties={\n",
" \"x_foo\": \"bar\"\n",
" })\n",
"print(identity)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Alternatively, setting ``allow_custom`` to ``True`` will allow custom properties without requiring a ``custom_properties`` dictionary."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.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;x_foo&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;bar&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;identity&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;identity--1e8188eb-245f-400b-839d-7f612169c514&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T21:02:22.708Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T21:02:22.708Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;John Smith&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;identity_class&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;individual&quot;</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"identity2 = Identity(name=\"John Smith\",\n",
" identity_class=\"individual\",\n",
" x_foo=\"bar\",\n",
" allow_custom=True)\n",
"print(identity2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Likewise, when parsing STIX content with custom properties, pass ``allow_custom=True`` to ``parse()``:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"bar\n"
]
}
],
"source": [
"from stix2 import parse\n",
"\n",
"input_string = \"\"\"{\n",
" \"type\": \"identity\",\n",
" \"id\": \"identity--311b2d2d-f010-5473-83ec-1edf84858f4c\",\n",
" \"created\": \"2015-12-21T19:59:11Z\",\n",
" \"modified\": \"2015-12-21T19:59:11Z\",\n",
" \"name\": \"John Smith\",\n",
" \"identity_class\": \"individual\",\n",
" \"x_foo\": \"bar\"\n",
"}\"\"\"\n",
"identity3 = parse(input_string, allow_custom=True)\n",
"print(identity3.x_foo)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Custom STIX Object Types\n",
"\n",
"To create a custom STIX object type, define a class with the ``@CustomObject`` decorator. It takes the type name and a list of property tuples, each tuple consisting of the property name and a property instance. Any special validation of the properties can be added by supplying an ``__init__`` function.\n",
"\n",
"Let's say zoo animals have become a serious cyber threat and we want to model them in STIX using a custom object type. Let's use a ``species`` property to store the kind of animal, and make that property required. We also want a property to store the class of animal, such as \"mammal\" or \"bird\" but only want to allow specific values in it. We can add some logic to validate this property in ``__init__``."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from stix2 import CustomObject, properties\n",
"\n",
"@CustomObject('x-animal', [\n",
" ('species', properties.StringProperty(required=True)),\n",
" ('animal_class', properties.StringProperty()),\n",
"])\n",
"class Animal(object):\n",
" def __init__(self, animal_class=None, **kwargs):\n",
" if animal_class and animal_class not in ['mammal', 'bird', 'fish', 'reptile']:\n",
" raise ValueError(\"'%s' is not a recognized class of animal.\" % animal_class)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we can create an instance of our custom ``Animal`` type."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.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;x-animal&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;x-animal--caebdf17-9d2a-4c84-8864-7406326618f0&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T21:02:34.724Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T21:02:34.724Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;species&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;lion&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;animal_class&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;mammal&quot;</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"animal = Animal(species=\"lion\",\n",
" animal_class=\"mammal\")\n",
"print(animal)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Trying to create an ``Animal`` instance with an ``animal_class`` that's not in the list will result in an error:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"ename": "ValueError",
"evalue": "'alien' is not a recognized class of animal.",
"output_type": "error",
"traceback": [
"\u001b[0;31mValueError\u001b[0m\u001b[0;31m:\u001b[0m 'alien' is not a recognized class of animal.\n"
]
}
],
"source": [
"Animal(species=\"xenomorph\",\n",
" animal_class=\"alien\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Parsing custom object types that you have already defined is simple and no different from parsing any other STIX object."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"shark\n"
]
}
],
"source": [
"input_string2 = \"\"\"{\n",
" \"type\": \"x-animal\",\n",
" \"id\": \"x-animal--941f1471-6815-456b-89b8-7051ddf13e4b\",\n",
" \"created\": \"2015-12-21T19:59:11Z\",\n",
" \"modified\": \"2015-12-21T19:59:11Z\",\n",
" \"species\": \"shark\",\n",
" \"animal_class\": \"fish\"\n",
"}\"\"\"\n",
"animal2 = parse(input_string2)\n",
"print(animal2.species)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"However, parsing custom object types which you have not defined will result in an error:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"ename": "ParseError",
"evalue": "Can't parse unknown object type 'x-foobar'! For custom types, use the CustomObject decorator.",
"output_type": "error",
"traceback": [
"\u001b[0;31mParseError\u001b[0m\u001b[0;31m:\u001b[0m Can't parse unknown object type 'x-foobar'! For custom types, use the CustomObject decorator.\n"
]
}
],
"source": [
"input_string3 = \"\"\"{\n",
" \"type\": \"x-foobar\",\n",
" \"id\": \"x-foobar--d362beb5-a04e-4e6b-a030-b6935122c3f9\",\n",
" \"created\": \"2015-12-21T19:59:11Z\",\n",
" \"modified\": \"2015-12-21T19:59:11Z\",\n",
" \"bar\": 1,\n",
" \"baz\": \"frob\"\n",
"}\"\"\"\n",
"parse(input_string3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Custom Cyber Observable Types\n",
"\n",
"Similar to custom STIX object types, use a decorator to create custom Cyber Observable types. Just as before, ``__init__()`` can hold additional validation, but it is not necessary."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.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;x-new-observable&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;a_property&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;something&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;property_2&quot;</span><span class=\"p\">:</span> <span class=\"mi\">10</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from stix2 import CustomObservable\n",
"\n",
"@CustomObservable('x-new-observable', [\n",
" ('a_property', properties.StringProperty(required=True)),\n",
" ('property_2', properties.IntegerProperty()),\n",
"])\n",
"class NewObservable():\n",
" pass\n",
"\n",
"new_observable = NewObservable(a_property=\"something\",\n",
" property_2=10)\n",
"print(new_observable)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"Likewise, after the custom Cyber Observable type has been defined, it can be parsed."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"foobaz\n",
"5\n"
]
}
],
"source": [
"from stix2 import ObservedData\n",
"\n",
"input_string4 = \"\"\"{\n",
" \"type\": \"observed-data\",\n",
" \"id\": \"observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf\",\n",
" \"created_by_ref\": \"identity--f431f809-377b-45e0-aa1c-6a4751cae5ff\",\n",
" \"created\": \"2016-04-06T19:58:16.000Z\",\n",
" \"modified\": \"2016-04-06T19:58:16.000Z\",\n",
" \"first_observed\": \"2015-12-21T19:00:00Z\",\n",
" \"last_observed\": \"2015-12-21T19:00:00Z\",\n",
" \"number_observed\": 50,\n",
" \"objects\": {\n",
" \"0\": {\n",
" \"type\": \"x-new-observable\",\n",
" \"a_property\": \"foobaz\",\n",
" \"property_2\": 5\n",
" }\n",
" }\n",
"}\"\"\"\n",
"obs_data = parse(input_string4)\n",
"print(obs_data.objects[\"0\"].a_property)\n",
"print(obs_data.objects[\"0\"].property_2)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"### Custom Cyber Observable Extensions\n",
"\n",
"Finally, custom extensions to existing Cyber Observable types can also be created. Just use the ``@CustomExtension`` decorator. Note that you must provide the Cyber Observable class to which the extension applies. Again, any extra validation of the properties can be implemented by providing an ``__init__()`` but it is not required. Let's say we want to make an extension to the ``File`` Cyber Observable Object:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.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;property1&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;something&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;property2&quot;</span><span class=\"p\">:</span> <span class=\"mi\">10</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from stix2 import File, CustomExtension\n",
"\n",
"@CustomExtension(File, 'x-new-ext', [\n",
" ('property1', properties.StringProperty(required=True)),\n",
" ('property2', properties.IntegerProperty()),\n",
"])\n",
"class NewExtension():\n",
" pass\n",
"\n",
"new_ext = NewExtension(property1=\"something\",\n",
" property2=10)\n",
"print(new_ext)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Once the custom Cyber Observable extension has been defined, it can be parsed."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"bla\n",
"50\n"
]
}
],
"source": [
"input_string5 = \"\"\"{\n",
" \"type\": \"observed-data\",\n",
" \"id\": \"observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf\",\n",
" \"created_by_ref\": \"identity--f431f809-377b-45e0-aa1c-6a4751cae5ff\",\n",
" \"created\": \"2016-04-06T19:58:16.000Z\",\n",
" \"modified\": \"2016-04-06T19:58:16.000Z\",\n",
" \"first_observed\": \"2015-12-21T19:00:00Z\",\n",
" \"last_observed\": \"2015-12-21T19:00:00Z\",\n",
" \"number_observed\": 50,\n",
" \"objects\": {\n",
" \"0\": {\n",
" \"type\": \"file\",\n",
" \"name\": \"foo.bar\",\n",
" \"hashes\": {\n",
" \"SHA-256\": \"35a01331e9ad96f751278b891b6ea09699806faedfa237d40513d92ad1b7100f\"\n",
" },\n",
" \"extensions\": {\n",
" \"x-new-ext\": {\n",
" \"property1\": \"bla\",\n",
" \"property2\": 50\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\"\"\"\n",
"obs_data2 = parse(input_string5)\n",
"print(obs_data2.objects[\"0\"].extensions[\"x-new-ext\"].property1)\n",
"print(obs_data2.objects[\"0\"].extensions[\"x-new-ext\"].property2)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.12"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

307
docs/guide/datastore.ipynb Normal file
View File

@ -0,0 +1,307 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true,
"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",
" 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": {
"collapsed": true,
"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\n",
"from pygments.formatters import HtmlFormatter\n",
"from IPython.display import HTML\n",
"\n",
"original_print = print\n",
"\n",
"def json_print(inpt):\n",
" string = str(inpt)\n",
" if string[0] == '{':\n",
" formatter = HtmlFormatter()\n",
" return HTML('<style type=\"text/css\">{}</style>{}'.format(\n",
" formatter.get_style_defs('.highlight'),\n",
" highlight(string, JsonLexer(), formatter)))\n",
" else:\n",
" original_print(inpt)\n",
"\n",
"print = json_print"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# DataStore API\n",
"\n",
"CTI Python STIX2 features a new interface for pulling and pushing STIX2 content. The new interface consists of DataStore, DataSource and DataSink constructs: a DataSource for pulling STIX2 content, a DataSink for pushing STIX2 content, and a DataStore for pulling/pushing.\n",
"\n",
"The DataStore, DataSource, DataSink (referred to as \"DataStore suite\") APIs are not referenced directly by a user but are used as base classes, which are then sublcassed into real DataStore suite(s). CTI Python STIX2 provides for the DataStore suites of **FileSystem**, **Memory**, and **TAXII**. Users are also encrouraged subclassing the base Data suite and creating their own custom DataStore suites."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## CompositeDataSource\n",
"\n",
"**CompositeDataSource** is an available controller that can be used as a single interface to a set of defined DataSources. The purpose of this controller is allow for the grouping of **DataSources** and making get/query calls to a set of DataSources in one API call. **CompositeDataSource** can be used to organize/group **DataSources**, federate get()/all_versions()/query() calls, and reduce user code.\n",
"\n",
"**CompositeDataSource** is just a wrapper around a set of defined **DataSources** (e.g. FileSystemSource) that federates get()/all_versions()/query() calls individually to each of the attached **DataSources** , collects the results from each **DataSource** and returns them.\n",
"\n",
"Filters can be attached to **CompositeDataSources** just as they can be done to **DataStores** and **DataSources**. When get()/all_versions()/query() calls are made to the **CompositeDataSource**, it will pass along any query filters from the call and any of its own filters to the attached **DataSources**. To which, those attached **DataSources** may have their own attached filters as well. The effect is that all the filters are eventually combined when the get()/all_versions()/query() call is actually executed within a **DataSource**. \n",
"\n",
"A **CompositeDataSource** can also be attached to a **CompositeDataSource** for multiple layers of grouped **DataSources**.\n",
"\n",
"\n",
"### CompositeDataSource API\n",
"\n",
"#### CompositeDataSource Examples\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"type\": \"indicator\",\n",
" \"id\": \"indicator--797ae2b5-3f7a-44c5-8ecd-33ba22fdc2b5\",\n",
" \"created\": \"2017-10-04T19:27:41.000Z\",\n",
" \"modified\": \"2017-10-04T19:27:41.000Z\",\n",
" \"labels\": [\n",
" \"malicious-activity\"\n",
" ],\n",
" \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n",
" \"pattern\": \"[ ipv4-addr:value = '98.138.19.88' ]\",\n",
" \"valid_from\": \"2017-10-04T19:27:41Z\",\n",
" \"kill_chain_phases\": [\n",
" {\n",
" \"kill_chain_name\": \"lockheed-martin-cyber-kill-chain\",\n",
" \"phase_name\": \"delivery\"\n",
" }\n",
" ]\n",
"}\n",
"{\n",
" \"type\": \"indicator\",\n",
" \"id\": \"indicator--11913f42-2d52-4b9d-842f-94bf06819a66\",\n",
" \"created\": \"2017-10-04T19:27:41.000Z\",\n",
" \"modified\": \"2017-10-04T19:27:41.000Z\",\n",
" \"labels\": [\n",
" \"malicious-activity\"\n",
" ],\n",
" \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n",
" \"pattern\": \"[ ipv4-addr:value = '98.138.19.88' ]\",\n",
" \"valid_from\": \"2017-10-04T19:27:41Z\",\n",
" \"kill_chain_phases\": [\n",
" {\n",
" \"kill_chain_name\": \"lockheed-martin-cyber-kill-chain\",\n",
" \"phase_name\": \"delivery\"\n",
" }\n",
" ]\n",
"}\n"
]
}
],
"source": [
"from taxii2client import Collection\n",
"from stix2 import CompositeDataSource, FileSystemSource, TAXIICollectionSource\n",
"\n",
"# create FileSystemStore\n",
"fs = FileSystemSource(\"/tmp/stix2_data\")\n",
"\n",
"# create TAXIICollectionSource\n",
"colxn = Collection('https://test.freetaxii.com:8000/api1/collections/9cfa669c-ee94-4ece-afd2-f8edac37d8fd/')\n",
"ts = TAXIICollectionSource(colxn)\n",
"\n",
"# add them both to the CompositeDataSource\n",
"cs = CompositeDataSource()\n",
"cs.add_data_sources([fs, ts])\n",
"\n",
"# get an object that is only in the filesystem\n",
"ta = cs.get('intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a')\n",
"print(ta)\n",
"\n",
"# get an object that is only in the TAXII collection\n",
"ind = cs.get('indicator--37a6a5de-a5b9-425a-903a-4ae9cbf1ff3f')\n",
"print(ind)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Filters\n",
"\n",
"The CTI Python STIX2 **DataStore** suites - **FileSystem**, **Memory** and **TAXII** - all use the **Filters** module to allow for the querying of STIX content. The basic functionality is that filters can be created and supplied everytime to calls to **query()**, and/or attached to a **DataStore** so that every future query placed to that **DataStore** is evaluated against the attached filters, supplemented with any further filters supplied with the query call. Attached filters can also be removed from **DataStores**.\n",
"\n",
"Filters are very simple, as they consist of a field name, comparison operator and an object property value (i.e. value to compare to). Currently, CTI Python STIX2 supports **ONLY** STIX 2 object common properties and TAXII2 Filtering parameters for fields to filter on:\n",
"\n",
"Fields\n",
"\n",
"(STIX2 Object Common Properties)\n",
"\n",
"* created\n",
"* created_by_ref\n",
"* external_references.source_name\n",
"* external_references.description\n",
"* external_references.url\n",
"* external_references.external_id\n",
"* granular_markings.marking_ref\n",
"* granular_markings.selectors\n",
"* id\n",
"* labels\n",
"* modified\n",
"* object_marking_refs\n",
"* revoked\n",
"* type\n",
"\n",
"(TAXII2 filter fields)\n",
"\n",
"* added_after\n",
"* match[id]\n",
"* match[type]\n",
"* match[version]\n",
"\n",
"Supported operators on above properties:\n",
"\n",
"* =\n",
"* !=\n",
"* in\n",
"* >\n",
"* < \n",
"* ```>=```\n",
"* <=\n",
"\n",
"Value types of the common property values must be one of these (python) types:\n",
"\n",
"* bool\n",
"* dict\n",
"* float\n",
"* int\n",
"* list\n",
"* str\n",
"* tuple\n",
"\n",
"### Filter Examples"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import sys\n",
"from stix2 import Filter\n",
"\n",
"# create filter for STIX objects that have external references to MITRE ATT&CK framework\n",
"f = Filter(\"external_references.source_name\", \"=\", \"mitre-attack\")\n",
"\n",
"# create filter for STIX objects that are not of SDO type Attack-Pattnern\n",
"f1 = Filter(\"type\", \"!=\", \"attack-pattern\")\n",
"\n",
"# create filter for STIX objects that have the \"threat-report\" label\n",
"f2 = Filter(\"labels\", \"in\", \"threat-report\")\n",
"\n",
"# create filter for STIX objects that have been modified past the timestamp\n",
"f3 = Filter(\"modified\", \">=\", \"2017-01-28T21:33:10.772474Z\")\n",
"\n",
"# create filter for STIX objects that have been revoked\n",
"f4 = Filter(\"revoked\", \"=\", True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For Filters to be applied to a query, they must be either supplied with the query call or attached a **DataStore**, more specifically to **DataSource** whether that **DataSource** is a part of a **DataStore** or stands by itself. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from stix2 import MemoryStore, FileSystemStore, FileSystemSource\n",
"\n",
"fs = FileSystemStore(\"/home/michael/Desktop/sample_stix2_data\")\n",
"fs_source = FileSystemSource(\"/home/michael/Desktop/sample_stix2_data\")\n",
"\n",
"# attach filter to FileSystemStore\n",
"fs.source.filters.add(f)\n",
"\n",
"# attach multiple filters to FileSystemStore\n",
"fs.source.filters.update([f1,f2])\n",
"\n",
"# can also attach filters to a Source\n",
"# attach multiple filters to FileSystemSource\n",
"fs_source.filters.update([f3, f4])\n",
"\n",
"\n",
"mem = MemoryStore()\n",
"\n",
"# As it is impractical to only use MemorySink or MemorySource,\n",
"# attach a filter to a MemoryStore\n",
"mem.source.filters.add(f)\n",
"\n",
"# attach multiple filters to a MemoryStore\n",
"mem.source.filters.update([f1,f2])"
]
}
],
"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.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@ -0,0 +1,745 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true,
"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",
" 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": {
"collapsed": true,
"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\n",
"from pygments.formatters import HtmlFormatter\n",
"from IPython.display import HTML\n",
"\n",
"original_print = print\n",
"\n",
"def json_print(inpt):\n",
" string = str(inpt)\n",
" if string[0] == '{':\n",
" formatter = HtmlFormatter()\n",
" return HTML('<style type=\"text/css\">{}</style>{}'.format(\n",
" formatter.get_style_defs('.highlight'),\n",
" highlight(string, JsonLexer(), formatter)))\n",
" else:\n",
" original_print(inpt)\n",
"\n",
"print = json_print"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Using Environments\n",
"\n",
"An ``Environment`` object makes it easier to use STIX 2 content as part of a larger application or ecosystem. It allows you to abstract away the nasty details of sending and receiving STIX data, and to create STIX objects with default values for common properties.\n",
"\n",
"### Storing and Retrieving STIX Content\n",
"\n",
"An ``Environment`` can be set up with a ``DataStore`` if you want to store and retrieve STIX content from the same place. "
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from stix2 import Environment, MemoryStore\n",
"\n",
"env = Environment(store=MemoryStore())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If desired, you can instead set up an ``Environment`` with different data sources and sinks. In the following example we set up an environment that retrieves objects from memory and a directory on the filesystem, and stores objects in a different directory on the filesystem."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from stix2 import CompositeDataSource, FileSystemSink, FileSystemSource, MemorySource\n",
"\n",
"src = CompositeDataSource()\n",
"src.add_data_sources([MemorySource(), FileSystemSource(\"/tmp/stix_source\")])\n",
"env2 = Environment(source=src,\n",
" sink=FileSystemSink(\"/tmp/stix_sink\"))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Once you have an ``Environment`` you can store some STIX content in its DataSinks with ``add()``:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"from stix2 import Indicator\n",
"\n",
"indicator = Indicator(id=\"indicator--01234567-89ab-cdef-0123-456789abcdef\",\n",
" labels=[\"malicious-activity\"],\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")\n",
"env.add(indicator)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can retrieve STIX objects from the DataSources in the Environment with ``get()``, ``query()``, and ``all_versions()``, just as you would for a DataSource."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.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;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--01234567-89ab-cdef-0123-456789abcdef&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-10-02T13:20:39.373Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-10-02T13:20:39.373Z&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;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;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-10-02T13:20:39.3737Z&quot;</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"print(env.get(\"indicator--01234567-89ab-cdef-0123-456789abcdef\"))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Creating STIX Objects With Defaults\n",
"\n",
"To create STIX objects with default values for certain properties, use an ``ObjectFactory``. For instance, say we want all objects we create to have a ``created_by_ref`` property pointing to the ``Identity`` object representing our organization."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from stix2 import Indicator, ObjectFactory\n",
"\n",
"factory = ObjectFactory(created_by_ref=\"identity--311b2d2d-f010-5473-83ec-1edf84858f4c\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"Once you've set up the Object Factory, use its ``create()`` method, passing in the class for the type of object you wish to create, followed by the other properties and their values for the object."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.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;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--c92ad60d-449d-4adf-86b3-4e5951a8f480&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--311b2d2d-f010-5473-83ec-1edf84858f4c&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-10-02T13:23:00.607Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-10-02T13:23:00.607Z&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;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;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-10-02T13:23:00.607216Z&quot;</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ind = factory.create(Indicator,\n",
" labels=[\"malicious-activity\"],\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")\n",
"print(ind)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"All objects we create with that ``ObjectFactory`` will automatically get the default value for ``created_by_ref``. These are the properties for which defaults can be set:\n",
"\n",
"- ``created_by_ref``\n",
"- ``created``\n",
"- ``external_references``\n",
"- ``object_marking_refs``\n",
"\n",
"These defaults can be bypassed. For example, say you have an ``Environment`` with multiple default values but want to create an object with a different value for ``created_by_ref``, or none at all."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.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;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--ae206b9f-8723-4fcf-beb7-8b1b9a2570ab&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-25T18:07:46.255Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-25T18:07:46.255Z&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;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;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-10-02T13:23:05.790562Z&quot;</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"factory2 = ObjectFactory(created_by_ref=\"identity--311b2d2d-f010-5473-83ec-1edf84858f4c\",\n",
" created=\"2017-09-25T18:07:46.255472Z\")\n",
"env2 = Environment(factory=factory2)\n",
"\n",
"ind2 = env2.create(Indicator,\n",
" created_by_ref=None,\n",
" labels=[\"malicious-activity\"],\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")\n",
"print(ind2)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.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;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--a8e2be68-b496-463f-9ff4-f620046e7cf2&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--962cabe5-f7f3-438a-9169-585a8c971d12&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-25T18:07:46.255Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-25T18:07:46.255Z&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;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;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-10-02T13:23:08.32424Z&quot;</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ind3 = env2.create(Indicator,\n",
" created_by_ref=\"identity--962cabe5-f7f3-438a-9169-585a8c971d12\",\n",
" labels=[\"malicious-activity\"],\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")\n",
"print(ind3)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"For the full power of the Environment layer, create an Environment with both a DataStore/Source/Sink and an Object Factory:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.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;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--89ba04ea-cce9-47a3-acd3-b6379ce51581&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--311b2d2d-f010-5473-83ec-1edf84858f4c&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-10-02T13:23:29.629Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-10-02T13:23:29.629Z&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;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;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-10-02T13:23:29.629857Z&quot;</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"environ = Environment(ObjectFactory(created_by_ref=\"identity--311b2d2d-f010-5473-83ec-1edf84858f4c\"),\n",
" MemoryStore())\n",
"\n",
"i = environ.create(Indicator,\n",
" labels=[\"malicious-activity\"],\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")\n",
"environ.add(i)\n",
"print(environ.get(i.id))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.12"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

554
docs/guide/filesystem.ipynb Normal file
View File

@ -0,0 +1,554 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true,
"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",
" 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": {
"collapsed": true,
"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\n",
"from pygments.formatters import HtmlFormatter\n",
"from IPython.display import HTML\n",
"\n",
"original_print = print\n",
"\n",
"def json_print(inpt):\n",
" string = str(inpt)\n",
" if string[0] == '{':\n",
" formatter = HtmlFormatter()\n",
" return HTML('<style type=\"text/css\">{}</style>{}'.format(\n",
" formatter.get_style_defs('.highlight'),\n",
" highlight(string, JsonLexer(), formatter)))\n",
" else:\n",
" original_print(inpt)\n",
"\n",
"print = json_print"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## FileSystem \n",
"\n",
"The FileSystem suite contains **FileSystemStore **, **FileSystemSource** and **FileSystemSink**. Under the hood, all FileSystem objects point to a file directory (on disk) that contains STIX2 content. \n",
"\n",
"The directory and file structure of the intended STIX2 content should be:\n",
"\n",
"```\n",
"stix2_content/\n",
" /STIX2 Domain Object type\n",
" STIX2 Domain Object\n",
" STIX2 Domain Object\n",
" .\n",
" .\n",
" .\n",
" /STIX2 Domain Object type\n",
" STIX2 Domain Object\n",
" STIX2 Domain Object\n",
" .\n",
" .\n",
" .\n",
" .\n",
" .\n",
" .\n",
" /STIX2 Domain Object type\n",
"```\n",
"\n",
"Essentially a master STIX2 content directory where each subdirectory aligns to a STIX2 domain object type (i.e. \"attack-pattern\", \"campaign\", \"malware\" etc..). Within each STIX2 domain object subdirectory are json files that are STIX2 domain objects of the specified type. The name of the json files correspond to the ID of the STIX2 domain object found within that file. A real example of the FileSystem directory structure:\n",
"\n",
"```\n",
"stix2_content/\n",
" /attack-pattern\n",
" attack-pattern--00d0b012-8a03-410e-95de-5826bf542de6.json\n",
" attack-pattern--0a3ead4e-6d47-4ccb-854c-a6a4f9d96b22.json\n",
" attack-pattern--1b7ba276-eedc-4951-a762-0ceea2c030ec.json\n",
" /campaign\n",
" /course-of-action\n",
" course-of-action--2a8de25c-f743-4348-b101-3ee33ab5871b.json\n",
" course-of-action--2c3ce852-06a2-40ee-8fe6-086f6402a739.json\n",
" /identity\n",
" identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5.json\n",
" /indicator\n",
" /intrusion-set\n",
" /malware\n",
" malware--1d808f62-cf63-4063-9727-ff6132514c22.json\n",
" malware--2eb9b131-d333-4a48-9eb4-d8dec46c19ee.json\n",
" /observed-data\n",
" /report\n",
" /threat-actor\n",
" /vulnerability\n",
"```\n",
"\n",
"**FileSystemStore** is intended for use cases where STIX2 content is retrieved and pushed to the same file directory. As **FileSystemStore** is just a wrapper around a paired **FileSystemSource** and **FileSystemSink** that point the same file directory.\n",
"\n",
"Use cases where STIX2 content will only be retrieved or pushed, then a **FileSystemSource** and **FileSystemSink** can be used individually. Or for the use case where STIX2 content will be retrieved from one distinct file directory and pushed to another.\n",
"\n",
"### FileSystem API\n",
"\n",
"A note on **get()**, **all_versions()**, and **query()**. The format of the STIX2 content targeted by the FileSystem suite is json files. When STIX2 content (in json) is retrieved by the **FileSystemStore** from disk, the content will attempt to be parsed into full-featured python STIX2 objects and returned as such. \n",
"\n",
"A note on **add()**. When STIX content is added (pushed) to the file system, the STIX content can be supplied in the following forms: python STIX objects, python dicts (of valid STIX objects or Bundles), json-encoded strings (of valid STIX objects or Bundles), or a (python)list of any of the previously listed types. Any of the previous STIX content forms will be converted to a STIX json object (in a STIX Bundle) and written to disk. \n",
"\n",
"### FileSystem Examples\n",
"\n",
"#### FileSystemStore\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"type\": \"malware\",\n",
" \"id\": \"malware--00c3bfcb-99bd-4767-8c03-b08f585f5c8a\",\n",
" \"created_by_ref\": \"identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5\",\n",
" \"created\": \"2017-05-31T21:33:19.746Z\",\n",
" \"modified\": \"2017-05-31T21:33:19.746Z\",\n",
" \"name\": \"PowerDuke\",\n",
" \"description\": \"PowerDuke is a backdoor that was used by APT29 in 2016. It has primarily been delivered through Microsoft Word or Excel attachments containing malicious macros.[[Citation: Volexity PowerDuke November 2016]]\",\n",
" \"labels\": [\n",
" \"malware\"\n",
" ],\n",
" \"external_references\": [\n",
" {\n",
" \"source_name\": \"mitre-attack\",\n",
" \"url\": \"https://attack.mitre.org/wiki/Software/S0139\",\n",
" \"external_id\": \"S0139\"\n",
" },\n",
" {\n",
" \"source_name\": \"Volexity PowerDuke November 2016\",\n",
" \"description\": \"Adair, S.. (2016, November 9). PowerDuke: Widespread Post-Election Spear Phishing Campaigns Targeting Think Tanks and NGOs. Retrieved January 11, 2017.\",\n",
" \"url\": \"https://www.volexity.com/blog/2016/11/09/powerduke-post-election-spear-phishing-campaigns-targeting-think-tanks-and-ngos/\"\n",
" }\n",
" ],\n",
" \"object_marking_refs\": [\n",
" \"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168\"\n",
" ]\n",
"}\n"
]
}
],
"source": [
"from stix2 import FileSystemStore\n",
"\n",
"\"\"\"\n",
"Working with the FileSystemStore, where STIX content can be retrieved and pushed to a file system.\n",
"\"\"\"\n",
"\n",
"# create FileSystemStore\n",
"fs = FileSystemStore(\"/home/michael/Desktop/sample_stix2_data\")\n",
"\n",
"# retrieve STIX2 content from FileSystemStore\n",
"ap = fs.get(\"attack-pattern--00d0b012-8a03-410e-95de-5826bf542de6\")\n",
"mal = fs.get(\"malware--00c3bfcb-99bd-4767-8c03-b08f585f5c8a\")\n",
"\n",
"# for visual purposes\n",
"print(mal)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from stix2 import ThreatActor, Indicator\n",
"\n",
"# create new STIX threat-actor\n",
"ta = ThreatActor(name=\"Adjective Bear\",\n",
" labels=[\"nation-state\"],\n",
" sophistication=\"innovator\",\n",
" resource_level=\"government\",\n",
" goals=[\n",
" \"compromising media outlets\",\n",
" \"water-hole attacks geared towards political, military targets\",\n",
" \"intelligence collection\"\n",
" ])\n",
"\n",
"# create new indicators\n",
"ind = Indicator(description=\"Crusades C2 implant\",\n",
" labels=[\"malicious-activity\"],\n",
" pattern=\"[file:hashes.'SHA-256' = '54b7e05e39a59428743635242e4a867c932140a999f52a1e54fa7ee6a440c73b']\")\n",
"\n",
"ind1 = Indicator(description=\"Crusades C2 implant 2\",\n",
" labels=[\"malicious-activity\"],\n",
" pattern=\"[file:hashes.'SHA-256' = '64c7e05e40a59511743635242e4a867c932140a999f52a1e54fa7ee6a440c73b']\")\n",
"\n",
"# add STIX object (threat-actor) to FileSystemStore\n",
"fs.add(ta)\n",
"\n",
"# can also add multiple STIX objects to FileSystemStore in one call\n",
"fs.add([ind, ind1])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### FileSystemSource - (if STIX content is only to be retrieved from FileSystem)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"type\": \"attack-pattern\",\n",
" \"id\": \"attack-pattern--00d0b012-8a03-410e-95de-5826bf542de6\",\n",
" \"created_by_ref\": \"identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5\",\n",
" \"created\": \"2017-05-31T21:30:54.176Z\",\n",
" \"modified\": \"2017-05-31T21:30:54.176Z\",\n",
" \"name\": \"Indicator Removal from Tools\",\n",
" \"description\": \"If a malicious...command-line parameters, Process monitoring\",\n",
" \"kill_chain_phases\": [\n",
" {\n",
" \"kill_chain_name\": \"mitre-attack\",\n",
" \"phase_name\": \"defense-evasion\"\n",
" }\n",
" ],\n",
" \"external_references\": [\n",
" {\n",
" \"source_name\": \"mitre-attack\",\n",
" \"url\": \"https://attack.mitre.org/wiki/Technique/T1066\",\n",
" \"external_id\": \"T1066\"\n",
" }\n",
" ],\n",
" \"object_marking_refs\": [\n",
" \"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168\"\n",
" ]\n",
"}\n"
]
}
],
"source": [
"from stix2 import FileSystemSource\n",
"\"\"\"\n",
"Working with FileSystemSource for retrieveing STIX content.\n",
"\"\"\"\n",
"\n",
"# create FileSystemSource\n",
"fs_source = FileSystemSource(\"/home/michael/Desktop/sample_stix2_data\")\n",
"\n",
"# retrieve STIX 2 objects\n",
"ap = fs_source.get(\"attack-pattern--00d0b012-8a03-410e-95de-5826bf542de6\")\n",
"\n",
"# for visual purposes\n",
"print(ap)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"type\": \"malware\",\n",
" \"id\": \"malware--0f862b01-99da-47cc-9bdb-db4a86a95bb1\",\n",
" \"created_by_ref\": \"identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5\",\n",
" \"created\": \"2017-05-31T21:32:54.772Z\",\n",
" \"modified\": \"2017-05-31T21:32:54.772Z\",\n",
" \"name\": \"Emissary\",\n",
" \"description\": \"Emissary is a Trojan that has been used by Lotus Blossom. It shares code with Elise, with both Trojans being part of a malware group referred to as LStudio.[[Citation: Lotus Blossom Dec 2015]]\",\n",
" \"labels\": [\n",
" \"malware\"\n",
" ],\n",
" \"external_references\": [\n",
" {\n",
" \"source_name\": \"mitre-attack\",\n",
" \"url\": \"https://attack.mitre.org/wiki/Software/S0082\",\n",
" \"external_id\": \"S0082\"\n",
" },\n",
" {\n",
" \"source_name\": \"Lotus Blossom Dec 2015\",\n",
" \"description\": \"Falcone, R. and Miller-Osborn, J.. (2015, December 18). Attack on French Diplomat Linked to Operation Lotus Blossom. Retrieved February 15, 2016.\",\n",
" \"url\": \"http://researchcenter.paloaltonetworks.com/2015/12/attack-on-french-diplomat-linked-to-operation-lotus-blossom/\"\n",
" }\n",
" ],\n",
" \"object_marking_refs\": [\n",
" \"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168\"\n",
" ]\n",
"}\n",
"{\n",
" \"type\": \"malware\",\n",
" \"id\": \"malware--2a6f4c7b-e690-4cc7-ab6b-1f821fb6b80b\",\n",
" \"created_by_ref\": \"identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5\",\n",
" \"created\": \"2017-05-31T21:32:33.348Z\",\n",
" \"modified\": \"2017-05-31T21:32:33.348Z\",\n",
" \"name\": \"LOWBALL\",\n",
" \"description\": \"LOWBALL is malware used by admin@338. It was used in August 2015 in email messages targeting Hong Kong-based media organizations.[[Citation: FireEye admin@338]]\",\n",
" \"labels\": [\n",
" \"malware\"\n",
" ],\n",
" \"external_references\": [\n",
" {\n",
" \"source_name\": \"mitre-attack\",\n",
" \"url\": \"https://attack.mitre.org/wiki/Software/S0042\",\n",
" \"external_id\": \"S0042\"\n",
" },\n",
" {\n",
" \"source_name\": \"FireEye admin@338\",\n",
" \"description\": \"FireEye Threat Intelligence. (2015, December 1). China-based Cyber Threat Group Uses Dropbox for Malware Communications and Targets Hong Kong Media Outlets. Retrieved December 4, 2015.\",\n",
" \"url\": \"https://www.fireeye.com/blog/threat-research/2015/11/china-based-threat.html\"\n",
" }\n",
" ],\n",
" \"object_marking_refs\": [\n",
" \"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168\"\n",
" ]\n",
"}\n",
"{\n",
" \"type\": \"malware\",\n",
" \"id\": \"malware--00c3bfcb-99bd-4767-8c03-b08f585f5c8a\",\n",
" \"created_by_ref\": \"identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5\",\n",
" \"created\": \"2017-05-31T21:33:19.746Z\",\n",
" \"modified\": \"2017-05-31T21:33:19.746Z\",\n",
" \"name\": \"PowerDuke\",\n",
" \"description\": \"PowerDuke is a backdoor that was used by APT29 in 2016. It has primarily been delivered through Microsoft Word or Excel attachments containing malicious macros.[[Citation: Volexity PowerDuke November 2016]]\",\n",
" \"labels\": [\n",
" \"malware\"\n",
" ],\n",
" \"external_references\": [\n",
" {\n",
" \"source_name\": \"mitre-attack\",\n",
" \"url\": \"https://attack.mitre.org/wiki/Software/S0139\",\n",
" \"external_id\": \"S0139\"\n",
" },\n",
" {\n",
" \"source_name\": \"Volexity PowerDuke November 2016\",\n",
" \"description\": \"Adair, S.. (2016, November 9). PowerDuke: Widespread Post-Election Spear Phishing Campaigns Targeting Think Tanks and NGOs. Retrieved January 11, 2017.\",\n",
" \"url\": \"https://www.volexity.com/blog/2016/11/09/powerduke-post-election-spear-phishing-campaigns-targeting-think-tanks-and-ngos/\"\n",
" }\n",
" ],\n",
" \"object_marking_refs\": [\n",
" \"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168\"\n",
" ]\n",
"}\n",
"{\n",
" \"type\": \"malware\",\n",
" \"id\": \"malware--0db09158-6e48-4e7c-8ce7-2b10b9c0c039\",\n",
" \"created_by_ref\": \"identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5\",\n",
" \"created\": \"2017-05-31T21:32:55.126Z\",\n",
" \"modified\": \"2017-05-31T21:32:55.126Z\",\n",
" \"name\": \"Misdat\",\n",
" \"description\": \"Misdat is a backdoor that was used by Dust Storm from 2010 to 2011.[[Citation: Cylance Dust Storm]]\",\n",
" \"labels\": [\n",
" \"malware\"\n",
" ],\n",
" \"external_references\": [\n",
" {\n",
" \"source_name\": \"mitre-attack\",\n",
" \"url\": \"https://attack.mitre.org/wiki/Software/S0083\",\n",
" \"external_id\": \"S0083\"\n",
" },\n",
" {\n",
" \"source_name\": \"Cylance Dust Storm\",\n",
" \"description\": \"Gross, J. (2016, February 23). Operation Dust Storm. Retrieved February 25, 2016.\",\n",
" \"url\": \"https://www.cylance.com/hubfs/2015%20cylance%20website/assets/operation-dust-storm/Op%20Dust%20Storm%20Report.pdf?t=1456259131512\"\n",
" }\n",
" ],\n",
" \"object_marking_refs\": [\n",
" \"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168\"\n",
" ]\n",
"}\n",
"{\n",
" \"type\": \"malware\",\n",
" \"id\": \"malware--1d808f62-cf63-4063-9727-ff6132514c22\",\n",
" \"created_by_ref\": \"identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5\",\n",
" \"created\": \"2017-05-31T21:33:06.433Z\",\n",
" \"modified\": \"2017-05-31T21:33:06.433Z\",\n",
" \"name\": \"WEBC2\",\n",
" \"description\": \"WEBC2 is a backdoor used by APT1 to retrieve a Web page from a predetermined C2 server.[[Citation: Mandiant APT1 Appendix]]\",\n",
" \"labels\": [\n",
" \"malware\"\n",
" ],\n",
" \"external_references\": [\n",
" {\n",
" \"source_name\": \"mitre-attack\",\n",
" \"url\": \"https://attack.mitre.org/wiki/Software/S0109\",\n",
" \"external_id\": \"S0109\"\n",
" },\n",
" {\n",
" \"source_name\": \"Mandiant APT1 Appendix\",\n",
" \"description\": \"Mandiant. (n.d.). Appendix C (Digital) - The Malware Arsenal. Retrieved July 18, 2016.\",\n",
" \"url\": \"https://www.fireeye.com/content/dam/fireeye-www/services/pdfs/mandiant-apt1-report-appendix.zip\"\n",
" }\n",
" ],\n",
" \"object_marking_refs\": [\n",
" \"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168\"\n",
" ]\n",
"}\n"
]
}
],
"source": [
"from stix2 import Filter\n",
"\n",
"# create filter for type=malware\n",
"query = [Filter(\"type\", \"=\", \"malware\")]\n",
"\n",
"# query on the filter\n",
"mals = fs_source.query(query)\n",
"\n",
"for mal in mals:\n",
" print(mal)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"type\": \"malware\",\n",
" \"id\": \"malware--00c3bfcb-99bd-4767-8c03-b08f585f5c8a\",\n",
" \"created_by_ref\": \"identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5\",\n",
" \"created\": \"2017-05-31T21:33:19.746Z\",\n",
" \"modified\": \"2017-05-31T21:33:19.746Z\",\n",
" \"name\": \"PowerDuke\",\n",
" \"description\": \"PowerDuke is a backdoor that was used by APT29 in 2016. It has primarily been delivered through Microsoft Word or Excel attachments containing malicious macros.[[Citation: Volexity PowerDuke November 2016]]\",\n",
" \"labels\": [\n",
" \"malware\"\n",
" ],\n",
" \"external_references\": [\n",
" {\n",
" \"source_name\": \"mitre-attack\",\n",
" \"url\": \"https://attack.mitre.org/wiki/Software/S0139\",\n",
" \"external_id\": \"S0139\"\n",
" },\n",
" {\n",
" \"source_name\": \"Volexity PowerDuke November 2016\",\n",
" \"description\": \"Adair, S.. (2016, November 9). PowerDuke: Widespread Post-Election Spear Phishing Campaigns Targeting Think Tanks and NGOs. Retrieved January 11, 2017.\",\n",
" \"url\": \"https://www.volexity.com/blog/2016/11/09/powerduke-post-election-spear-phishing-campaigns-targeting-think-tanks-and-ngos/\"\n",
" }\n",
" ],\n",
" \"object_marking_refs\": [\n",
" \"marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168\"\n",
" ]\n",
"}\n"
]
}
],
"source": [
"# add more filters to the query\n",
"query.append(Filter(\"modified\", \">\" , \"2017-05-31T21:33:10.772474Z\"))\n",
"\n",
"mals = fs_source.query(query)\n",
"\n",
"# for visual purposes\n",
"for mal in mals:\n",
" print(mal)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### FileSystemSink - (if STIX content is only to be pushed to FileSystem)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from stix2 import FileSystemSink, Campaign\n",
"\"\"\"\n",
"Working with FileSystemSink for pushing STIX content.\n",
"\"\"\"\n",
"# create FileSystemSink\n",
"fs_sink = FileSystemSink(\"/home/michael/Desktop/sample_stix2_data\")\n",
"\n",
"# create STIX objects and add to sink\n",
"camp = Campaign(name=\"The Crusades\",\n",
" objective=\"Infiltrating Israeli, Iranian and Palestinian digital infrastructure and government systems.\",\n",
" aliases=[\"Desert Moon\"])\n",
"\n",
"ind = Indicator(description=\"Crusades C2 implant\",\n",
" labels=[\"malicious-activity\"],\n",
" pattern=\"[file:hashes.'SHA-256' = '54b7e05e39a59428743635242e4a867c932140a999f52a1e54fa7ee6a440c73b']\")\n",
"\n",
"ind1 = Indicator(description=\"Crusades C2 implant\",\n",
" labels=[\"malicious-activity\"],\n",
" pattern=\"[file:hashes.'SHA-256' = '54b7e05e39a59428743635242e4a867c932140a999f52a1e54fa7ee6a440c73b']\")\n",
"\n",
"# add Campaign object to FileSystemSink\n",
"fs_sink.add(camp)\n",
"\n",
"# can also add STIX objects to FileSystemSink in on call\n",
"fs_sink.add([ind, ind1])"
]
}
],
"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.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

1332
docs/guide/markings.ipynb Normal file

File diff suppressed because it is too large Load Diff

310
docs/guide/memory.ipynb Normal file
View File

@ -0,0 +1,310 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true,
"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",
" 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": {
"collapsed": true,
"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\n",
"from pygments.formatters import HtmlFormatter\n",
"from IPython.display import HTML\n",
"\n",
"original_print = print\n",
"\n",
"def json_print(inpt):\n",
" string = str(inpt)\n",
" if string[0] == '{':\n",
" formatter = HtmlFormatter()\n",
" return HTML('<style type=\"text/css\">{}</style>{}'.format(\n",
" formatter.get_style_defs('.highlight'),\n",
" highlight(string, JsonLexer(), formatter)))\n",
" else:\n",
" original_print(inpt)\n",
"\n",
"print = json_print"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Memory\n",
"\n",
"The Memory suite consists of **MemoryStore**, **MemorySource**, and **MemorySink**. Under the hood, the Memory suite points to an in-memory dictionary. Similarly, the **MemoryStore** is a just a wrapper around a paired **MemorySource** and **MemorySink**; as there is quite limited uses for just a **MemorySource** or a **MemorySink**, it is recommended to always use **MemoryStore**. The **MemoryStore** is intended for retrieving/searching and pushing STIX content to memory. It is important to note that all STIX content in memory is not backed up on the file system (disk), as that functionality is ecompassed within the **FileSystemStore**. However, the Memory suite does provide some utility methods for saving and loading STIX content to disk. **MemoryStore.save_to_file()** allows for saving all the STIX content that is in memory to a json file. **MemoryStore.load_from_file()** allows for loading STIX content from a json-formatted file. \n",
"\n",
"\n",
"### Memory API\n",
"\n",
"A note on **load_from_file()** and **save()**. These methods both add STIX content to an internal dictionary (maintained by MemoryStore). STIX content that is to be added can be in the following forms: python STIX objects, python dicts (of valid STIX objects or Bundles), json-encoded strings (of valid STIX objects or Bundles), or a (python)list of any of the previously listed types. **MemoryStore** actually stores STIX content either as python STIX objects or as python dictionaries, reducing and converting any of the aforementioned types to one of those; and whatever form the STIX object is stored as , is what it will be returned as when queried or retrieved. Python STIX objects, and json-encoded strings (of STIX content) are stored as python STIX objects. Python dicts (of STIX objects) are stored as python dictionaries. This is done, as can be efficiently supported, in order to return STIX content in the form it was added to the **MemoryStore**. Also, for **load_from_file()**, STIX content is assumed to be in json form within the file, individually or in a Bundle. \n",
"\n",
"A note on **save_to_file()**. This method dumps all STIX content that is in MemoryStore to the specified file. The file format will be json, and the STIX content will be within a STIX Bundle. ntoe, the the output form will be a json STIX Bundle regardless of the form that the individual STIX objects are stored(i.e. supplied) to the MemoryStore. \n",
"\n",
"### Memory Examples\n",
"\n",
"#### MemoryStore"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"type\": \"indicator\",\n",
" \"id\": \"indicator--d91ef175-8a82-470a-a610-bbd2ee8a1516\",\n",
" \"created\": \"2017-09-29T19:52:16.930Z\",\n",
" \"modified\": \"2017-09-29T19:52:16.930Z\",\n",
" \"labels\": [\n",
" \"malicious-activity\"\n",
" ],\n",
" \"description\": \"Crusades C2 implant\",\n",
" \"pattern\": \"[file:hashes.'SHA-256' = '54b7e05e39a59428743635242e4a867c932140a999f52a1e54fa7ee6a440c73b']\",\n",
" \"valid_from\": \"2017-09-29T19:52:16.930909Z\"\n",
"}\n"
]
}
],
"source": [
"from stix2 import MemoryStore, Indicator\n",
"\n",
"# create default MemoryStore\n",
"mem = MemoryStore()\n",
"\n",
"# insert newly created indicator into memory\n",
"ind = Indicator(description=\"Crusades C2 implant\",\n",
" labels=[\"malicious-activity\"],\n",
" pattern=\"[file:hashes.'SHA-256' = '54b7e05e39a59428743635242e4a867c932140a999f52a1e54fa7ee6a440c73b']\")\n",
"\n",
"mem.add(ind)\n",
"\n",
"# for visual purposes\n",
"print(mem.get(ind.id))\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"type\": \"indicator\",\n",
" \"id\": \"indicator--79fdaad7-c461-49bb-ad1d-caa5e9c51c90\",\n",
" \"created\": \"2017-09-29T19:52:17.021Z\",\n",
" \"modified\": \"2017-09-29T19:52:17.021Z\",\n",
" \"labels\": [\n",
" \"malicious-activity\"\n",
" ],\n",
" \"description\": \"Crusades stage 2 implant variant\",\n",
" \"pattern\": \"[file:hashes.'SHA-256' = '31a45e777e4d58b97f4c43e38006f8cd6580ddabc4037905b2fad734712b582c']\",\n",
" \"valid_from\": \"2017-09-29T19:52:17.021728Z\"\n",
"}\n"
]
}
],
"source": [
"from stix2 import Malware\n",
"\n",
"# add multiple STIX objects into memory\n",
"ind2 = Indicator(description=\"Crusades stage 2 implant\",\n",
" labels=[\"malicious-activity\"],\n",
" pattern=\"[file:hashes.'SHA-256' = '70fa62fb218dd9d936ee570dbe531dfa4e7c128ff37e6af7a6a6b2485487e50a']\")\n",
"ind3 = Indicator(description=\"Crusades stage 2 implant variant\",\n",
" labels=[\"malicious-activity\"],\n",
" pattern=\"[file:hashes.'SHA-256' = '31a45e777e4d58b97f4c43e38006f8cd6580ddabc4037905b2fad734712b582c']\")\n",
"mal = Malware(labels=[\"rootkit\"], name= \"Alexios\")\n",
"\n",
"mem.add([ind2,ind3, mal])\n",
"\n",
"# for visual purposes\n",
"print(mem.get(ind3.id))"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"-----------------------\n",
"{'name': 'Urban2', 'created': '2017-09-12T13:26:18.023Z', 'labels': ['rootkit'], 'modified': '2017-09-12T13:26:18.023Z', 'type': 'malware', 'id': 'malware--2daa14d6-cbf3-4308-bb8e-226d324a08e4'}\n",
"-----------------------\n",
"{\n",
" \"type\": \"malware\",\n",
" \"id\": \"malware--2b3dd412-18a5-4e81-8742-4977068eb3eb\",\n",
" \"created\": \"2017-09-29T19:52:17.028Z\",\n",
" \"modified\": \"2017-09-29T19:52:17.028Z\",\n",
" \"name\": \"Alexios\",\n",
" \"labels\": [\n",
" \"rootkit\"\n",
" ]\n",
"}\n"
]
}
],
"source": [
"from stix2 import Filter\n",
"\n",
"# add dictionary (of STIX object) to MemoryStore\n",
"# (this dict would assumably come from output of another source,\n",
"# i.e. a loaded json file, NOT manually created as done here for sample purposes)\n",
"\n",
"malware = {\n",
" \"type\": \"malware\",\n",
" \"id\" : \"malware--2daa14d6-cbf3-4308-bb8e-226d324a08e4\",\n",
" \"labels\": [\"rootkit\"],\n",
" \"name\": \"Urban2\",\n",
" \"created\": \"2017-09-12T13:26:18.023Z\",\n",
" \"modified\": \"2017-09-12T13:26:18.023Z\"\n",
"}\n",
"\n",
"mem.add(malware)\n",
"\n",
"results = mem.query([Filter(\"labels\",\"=\", \"rootkit\")])\n",
"for r in results:\n",
" # note that python STIX objects are pretty-printed\n",
" # due to some python dunder method magic, but normal\n",
" # python dictionaries are not by default. Thus the\n",
" # python STIX objects and python STIX dictionaries\n",
" # that match the above query can be easily identified visually\n",
" print(\"-----------------------\")\n",
" print(r)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"type\": \"report\",\n",
" \"id\": \"report--2add14d6-bbf3-4308-bb8e-226d314a08e4\",\n",
" \"created\": \"2017-05-08T18:34:08.042Z\",\n",
" \"modified\": \"2017-05-08T18:34:08.042Z\",\n",
" \"name\": \"The Crusades: Looking into the relentless infiltration of Israels digital infrastructure.\",\n",
" \"published\": \"2017-05-08T10:24:11.011Z\",\n",
" \"object_refs\": [\n",
" \"malware--2daa14d6-cbf3-4308-bb8e-226d324a08e4\"\n",
" ],\n",
" \"labels\": [\n",
" \"threat-report\"\n",
" ]\n",
"}\n"
]
}
],
"source": [
"from stix2 import Filter\n",
"\n",
"# add json formatted string to MemoryStore\n",
"# Again, would NOT manual create json-formatted string\n",
"# but taken as an output form from another source\n",
"report = '{\"type\": \"report\",\"id\": \"report--2add14d6-bbf3-4308-bb8e-226d314a08e4\",\"labels\": [\"threat-report\"], \"name\": \"The Crusades: Looking into the relentless infiltration of Israels digital infrastructure.\", \"published\": \"2017-05-08T10:24:11.011Z\", \"object_refs\":[\"malware--2daa14d6-cbf3-4308-bb8e-226d324a08e4\"], \"created\": \"2017-05-08T18:34:08.042Z\", \"modified\": \"2017-05-08T18:34:08.042Z\"}'\n",
"\n",
"mem.add(report)\n",
"\n",
"print(mem.get(\"report--2add14d6-bbf3-4308-bb8e-226d314a08e4\"))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### load_from_file() and save_to_file()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{u'name': u'The Crusades: Looking into the relentless infiltration of Israels digital infrastructure.', u'created': u'2017-05-08T18:34:08.042Z', u'labels': [u'threat-report'], u'modified': u'2017-05-08T18:34:08.042Z', u'object_refs': [u'malware--2daa14d6-cbf3-4308-bb8e-226d324a08e4'], u'published': u'2017-05-08T10:24:11.011Z', u'type': u'report', u'id': u'report--2add14d6-bbf3-4308-bb8e-226d314a08e4'}\n"
]
}
],
"source": [
"mem_2 = MemoryStore()\n",
"\n",
"# save (dump) all STIX content in MemoryStore to json file\n",
"mem.save_to_file(\"path_to_target_file.json\")\n",
"\n",
"# load(add) STIX content from json file into MemoryStore\n",
"mem_2.load_from_file(\"path_to_target_file.json\")\n",
"\n",
"report = mem_2.get(\"report--2add14d6-bbf3-4308-bb8e-226d314a08e4\")\n",
"\n",
"# for visualpurposes\n",
"# Note: Since STIX content was added to MemoryStore as json,\n",
"# it is maintained as python dictionaries ( as opposed to STIX objects)\n",
"print(report)"
]
}
],
"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.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

131
docs/guide/parsing.ipynb Normal file
View File

@ -0,0 +1,131 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true,
"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",
" 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": {
"collapsed": true,
"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\n",
"from pygments.formatters import HtmlFormatter\n",
"from IPython.display import HTML\n",
"\n",
"original_print = print\n",
"\n",
"def json_print(inpt):\n",
" string = str(inpt)\n",
" if string[0] == '{':\n",
" formatter = HtmlFormatter()\n",
" return HTML('<style type=\"text/css\">{}</style>{}'.format(\n",
" formatter.get_style_defs('.highlight'),\n",
" highlight(string, JsonLexer(), formatter)))\n",
" else:\n",
" original_print(inpt)\n",
"\n",
"print = json_print"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Parsing STIX Content"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Parsing STIX content is as easy as calling the `parse()` function on a JSON string. It will automatically determine the type of the object. The STIX objects within `bundle` objects, and the cyber observables contained within `observed-data` objects will be parsed as well."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"observed-data\n",
"0969de02ecf8a5f003e3f6d063d848c8a193aada092623f8ce408c15bcb5f038\n"
]
}
],
"source": [
"from stix2 import parse\n",
"\n",
"input_string = \"\"\"{\n",
" \"type\": \"observed-data\",\n",
" \"id\": \"observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf\",\n",
" \"created\": \"2016-04-06T19:58:16.000Z\",\n",
" \"modified\": \"2016-04-06T19:58:16.000Z\",\n",
" \"first_observed\": \"2015-12-21T19:00:00Z\",\n",
" \"last_observed\": \"2015-12-21T19:00:00Z\",\n",
" \"number_observed\": 50,\n",
" \"objects\": {\n",
" \"0\": {\n",
" \"type\": \"file\",\n",
" \"hashes\": {\n",
" \"SHA-256\": \"0969de02ecf8a5f003e3f6d063d848c8a193aada092623f8ce408c15bcb5f038\"\n",
" }\n",
" }\n",
" }\n",
"}\"\"\"\n",
"\n",
"obj = parse(input_string)\n",
"print(obj.type)\n",
"print(obj.objects[\"0\"].hashes['SHA-256'])"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.12"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@ -0,0 +1,200 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true,
"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",
" 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": {
"collapsed": true,
"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\n",
"from pygments.formatters import HtmlFormatter\n",
"from IPython.display import HTML\n",
"\n",
"original_print = print\n",
"\n",
"def json_print(inpt):\n",
" string = str(inpt)\n",
" if string[0] == '{':\n",
" formatter = HtmlFormatter()\n",
" return HTML('<style type=\"text/css\">{}</style>{}'.format(\n",
" formatter.get_style_defs('.highlight'),\n",
" highlight(string, JsonLexer(), formatter)))\n",
" else:\n",
" original_print(inpt)\n",
"\n",
"print = json_print"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Serializing STIX Objects"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The string representation of all STIX classes is a valid STIX JSON object."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.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;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--81b0644d-5e9d-48fb-bb83-aabe77918305&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:38:55.476Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:38:55.476Z&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;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;File hash for malware variant&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;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:38:55.476436Z&quot;</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": [
"from stix2 import Indicator\n",
"\n",
"indicator = Indicator(name=\"File hash for malware variant\",\n",
" labels=[\"malicious-activity\"],\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")\n",
"\n",
"print(str(indicator))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.12"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

2542
docs/guide/taxii.ipynb Normal file

File diff suppressed because it is too large Load Diff

344
docs/guide/versioning.ipynb Normal file
View File

@ -0,0 +1,344 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true,
"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",
" 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": {
"collapsed": true,
"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\n",
"from pygments.formatters import HtmlFormatter\n",
"from IPython.display import HTML\n",
"\n",
"original_print = print\n",
"\n",
"def json_print(inpt):\n",
" string = str(inpt)\n",
" if string[0] == '{':\n",
" formatter = HtmlFormatter()\n",
" return HTML('<style type=\"text/css\">{}</style>{}'.format(\n",
" formatter.get_style_defs('.highlight'),\n",
" highlight(string, JsonLexer(), formatter)))\n",
" else:\n",
" original_print(inpt)\n",
"\n",
"print = json_print"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Versioning"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To create a new version of an existing object, specify the property(ies) you want to change and their new values:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.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;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--92bb1ae4-db9c-4d6e-8ded-ef7280b4439a&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2016-01-01T08:00:00.000Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:39:07.149Z&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;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;File hash for Foobar malware&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;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:39:07.132129Z&quot;</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": [
"from stix2 import Indicator\n",
"\n",
"indicator = Indicator(created=\"2016-01-01T08:00:00.000Z\",\n",
" name=\"File hash for suspicious file\",\n",
" labels=[\"anomalous-activity\"],\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")\n",
"\n",
"indicator2 = indicator.new_version(name=\"File hash for Foobar malware\",\n",
" labels=[\"malicious-activity\"])\n",
"print(indicator2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The modified time will be updated to the current time unless you provide a specific value as a keyword argument. Note that you cant change the type, id, or created properties."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"scrolled": true
},
"outputs": [
{
"ename": "UnmodifiablePropertyError",
"evalue": "These properties cannot be changed when making a new version: id.",
"output_type": "error",
"traceback": [
"\u001b[0;31mUnmodifiablePropertyError\u001b[0m\u001b[0;31m:\u001b[0m These properties cannot be changed when making a new version: id.\n"
]
}
],
"source": [
"indicator.new_version(id=\"indicator--cc42e358-8b9b-493c-9646-6ecd73b41c21\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"To revoke an object:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.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;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--92bb1ae4-db9c-4d6e-8ded-ef7280b4439a&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2016-01-01T08:00:00.000Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:39:09.463Z&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;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;File hash for Foobar malware&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;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2017-09-26T23:39:07.132129Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;revoked&quot;</span><span class=\"p\">:</span> <span class=\"kc\">true</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"indicator2 = indicator2.revoke()\n",
"print(indicator2)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.12"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@ -7,12 +7,14 @@ Welcome to stix2's documentation!
=================================
.. toctree::
:maxdepth: 2
:maxdepth: 3
:caption: Contents:
overview
roadmap
guide
api_ref
datastore_api
roadmap
contributing

View File

@ -66,7 +66,7 @@ The **Environment Layer** adds several components that make it easier to handle
STIX 2 data as part of a larger application and as part of a larger cyber threat
intelligence ecosystem.
- ``Data Source``s represent locations from which STIX data can be retrieved,
- ``Data Source``\s represent locations from which STIX data can be retrieved,
such as a TAXII server, database, or local filesystem. The Data Source API
abstracts differences between these storage location, giving a common API to
get objects by ID or query by various properties, as well as allowing
@ -80,7 +80,7 @@ Each of these components can be used individually, or combined as part of an
``Environment``. These ``Environment`` objects allow different settings to be
used by different users of a multi-user application (such as a web application).
*This layer is currently being developed.*
*This layer is mostly complete.*
Workbench Layer
^^^^^^^^^^^^^^^
@ -94,4 +94,4 @@ Python, the Workbench Layer makes it easy to quickly interact with STIX data
from a variety of sources without needing to write and run one-off Python
scripts.
*This layer has not yet been started.*
*This layer is currently being developed.*

View File

@ -1,4 +1,5 @@
bumpversion
nbsphinx
pre-commit
pytest
pytest-cov

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.2.0
current_version = 0.3.0
commit = True
tag = True

View File

@ -1,4 +1,21 @@
"""Python APIs for STIX 2."""
"""Python APIs for STIX 2.
.. autosummary::
:toctree: api
common
core
environment
exceptions
markings
observables
patterns
properties
sdo
sources
sro
utils
"""
# flake8: noqa
@ -11,8 +28,8 @@ from .environment import Environment, ObjectFactory
from .markings import (add_markings, clear_markings, get_markings, is_marked,
remove_markings, set_markings)
from .observables import (URL, AlternateDataStream, ArchiveExt, Artifact,
AutonomousSystem, CustomObservable, Directory,
DomainName, EmailAddress, EmailMessage,
AutonomousSystem, CustomExtension, CustomObservable,
Directory, DomainName, EmailAddress, EmailMessage,
EmailMIMEComponent, File, HTTPRequestExt, ICMPExt,
IPv4Address, IPv6Address, MACAddress, Mutex,
NetworkTraffic, NTFSExt, PDFExt, Process,

View File

@ -1,4 +1,4 @@
"""Base class for type definitions in the stix2 library."""
"""Base classes for type definitions in the stix2 library."""
import collections
import copy

View File

@ -1,9 +1,9 @@
"""STIX 2 Common Data Types and Properties"""
"""STIX 2 Common Data Types and Properties."""
from collections import OrderedDict
from .base import _STIXBase
from .markings import MarkingsMixin
from .markings import _MarkingsMixin
from .properties import (HashesProperty, IDProperty, ListProperty, Property,
ReferenceProperty, SelectorProperty, StringProperty,
TimestampProperty, TypeProperty)
@ -70,7 +70,7 @@ class StatementMarking(_STIXBase):
class MarkingProperty(Property):
"""Represent the marking objects in the `definition` property of
"""Represent the marking objects in the ``definition`` property of
marking-definition objects.
"""
@ -81,7 +81,7 @@ class MarkingProperty(Property):
raise ValueError("must be a Statement, TLP Marking or a registered marking.")
class MarkingDefinition(_STIXBase, MarkingsMixin):
class MarkingDefinition(_STIXBase, _MarkingsMixin):
_type = 'marking-definition'
_properties = OrderedDict()
@ -126,17 +126,15 @@ def _register_marking(cls):
def CustomMarking(type='x-custom-marking', properties=None):
"""
Custom STIX Marking decorator.
"""Custom STIX Marking decorator.
Examples:
@CustomMarking('x-custom-marking', [
('property1', StringProperty(required=True)),
('property2', IntegerProperty()),
])
class MyNewMarkingObjectType():
pass
Example:
>>> @CustomMarking('x-custom-marking', [
... ('property1', StringProperty(required=True)),
... ('property2', IntegerProperty()),
... ])
... class MyNewMarkingObjectType():
... pass
"""
def custom_builder(cls):

View File

@ -1,4 +1,4 @@
"""STIX 2.0 Objects that are neither SDOs nor SROs"""
"""STIX 2.0 Objects that are neither SDOs nor SROs."""
from collections import OrderedDict

View File

@ -1,9 +1,13 @@
"""STIX 2 error classes.
"""
class STIXError(Exception):
"""Base class for errors generated in the stix2 library."""
class InvalidValueError(STIXError, ValueError):
"""An invalid value was provided to a STIX object's __init__."""
"""An invalid value was provided to a STIX object's ``__init__``."""
def __init__(self, cls, prop_name, reason):
super(InvalidValueError, self).__init__()
@ -45,7 +49,7 @@ class ExtraPropertiesError(STIXError, TypeError):
class ImmutableError(STIXError, ValueError):
"""Attempted to modify an object after creation"""
"""Attempted to modify an object after creation."""
def __init__(self, cls, key):
super(ImmutableError, self).__init__()
@ -85,7 +89,7 @@ class InvalidObjRefError(STIXError, ValueError):
class UnmodifiablePropertyError(STIXError, ValueError):
"""Attempted to modify an unmodifiable property of object when creating a new version"""
"""Attempted to modify an unmodifiable property of object when creating a new version."""
def __init__(self, unchangable_properties):
super(UnmodifiablePropertyError, self).__init__()
@ -139,7 +143,7 @@ class AtLeastOnePropertyError(STIXError, TypeError):
class RevokeError(STIXError, ValueError):
"""Attempted to an operation on a revoked object"""
"""Attempted to an operation on a revoked object."""
def __init__(self, called_by):
super(RevokeError, self).__init__()
@ -153,7 +157,7 @@ class RevokeError(STIXError, ValueError):
class ParseError(STIXError, ValueError):
"""Could not parse object"""
"""Could not parse object."""
def __init__(self, msg):
super(ParseError, self).__init__(msg)

View File

@ -1,8 +1,18 @@
"""
Python STIX 2.0 Data Markings API.
Functions and classes for working with STIX 2 Data Markings.
These high level functions will operate on both object level markings and
granular markings unless otherwise noted in each of the functions.
.. autosummary::
:toctree: markings
granular_markings
object_markings
utils
|
"""
from stix2.markings import granular_markings, object_markings
@ -214,14 +224,14 @@ def is_marked(obj, marking=None, selectors=None, inherited=False, descendants=Fa
return result
class MarkingsMixin():
class _MarkingsMixin():
pass
# Note that all of these methods will return a new object because of immutability
MarkingsMixin.get_markings = get_markings
MarkingsMixin.set_markings = set_markings
MarkingsMixin.remove_markings = remove_markings
MarkingsMixin.add_markings = add_markings
MarkingsMixin.clear_markings = clear_markings
MarkingsMixin.is_marked = is_marked
_MarkingsMixin.get_markings = get_markings
_MarkingsMixin.set_markings = set_markings
_MarkingsMixin.remove_markings = remove_markings
_MarkingsMixin.add_markings = add_markings
_MarkingsMixin.clear_markings = clear_markings
_MarkingsMixin.is_marked = is_marked

View File

@ -1,3 +1,5 @@
"""Functions for working with STIX 2.0 granular markings.
"""
from stix2 import exceptions
from stix2.markings import utils

View File

@ -1,3 +1,5 @@
"""Functions for working with STIX 2.0 object markings.
"""
from stix2 import exceptions
from stix2.markings import utils

View File

@ -1,3 +1,5 @@
"""Utility functions for STIX 2.0 data markings.
"""
import collections
@ -7,14 +9,14 @@ from stix2 import exceptions
def _evaluate_expression(obj, selector):
"""
Walks an SDO or SRO generating selectors to match against ``selector``. If
a match is found and the the value of this property is present in the
"""Walks an SDO or SRO generating selectors to match against ``selector``.
If a match is found and the the value of this property is present in the
objects. Matching value of the property will be returned.
Args:
obj: An SDO or SRO object.
selector: A string following the selector syntax.
selector (str): A string following the selector syntax.
Returns:
list: Values contained in matching property. Otherwise empty list.
@ -73,28 +75,26 @@ def convert_to_marking_list(data):
def compress_markings(granular_markings):
"""
Compress granular markings list. If there is more than one marking
identifier matches. It will collapse into a single granular marking.
"""Compress granular markings list.
Examples:
Input:
[
{
"selectors": [
"description"
],
"marking_ref": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9"
},
{
"selectors": [
"name"
],
"marking_ref": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9"
}
]
If there is more than one marking identifier matches. It will collapse into
a single granular marking.
Output:
Example:
>>> compress_markings([
... {
... "selectors": [
... "description"
... ],
... "marking_ref": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9"
... },
... {
... "selectors": [
... "name"
... ],
... "marking_ref": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9"
... }
... ])
[
{
"selectors": [
@ -132,23 +132,21 @@ def compress_markings(granular_markings):
def expand_markings(granular_markings):
"""
Expands granular markings list. If there is more than one selector per
granular marking. It will be expanded using the same marking_ref.
"""Expands granular markings list.
Examples:
Input:
[
{
"selectors": [
"description",
"name"
],
"marking_ref": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9"
}
]
If there is more than one selector per granular marking. It will be
expanded using the same marking_ref.
Output:
Example:
>>> expand_markings([
... {
... "selectors": [
... "description",
... "name"
... ],
... "marking_ref": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9"
... }
... ])
[
{
"selectors": [
@ -189,15 +187,16 @@ def expand_markings(granular_markings):
def build_granular_marking(granular_marking):
"""Returns a dictionary with the required structure for a granular
marking"""
"""Returns a dictionary with the required structure for a granular marking.
"""
return {"granular_markings": expand_markings(granular_marking)}
def iterpath(obj, path=None):
"""
Generator which walks the input ``obj`` model. Each iteration yields a
tuple containing a list of ancestors and the property value.
"""Generator which walks the input ``obj`` model.
Each iteration yields a tuple containing a list of ancestors and the
property value.
Args:
obj: An SDO or SRO object.

View File

@ -1,8 +1,8 @@
"""STIX 2.0 Cyber Observable Objects
"""STIX 2.0 Cyber Observable Objects.
Embedded observable object types, such as Email MIME Component, which is
embedded in Email Message objects, inherit from _STIXBase instead of Observable
and do not have a '_type' attribute.
embedded in Email Message objects, inherit from ``_STIXBase`` instead of
Observable and do not have a ``_type`` attribute.
"""
from collections import OrderedDict
@ -19,6 +19,8 @@ from .utils import get_dict
class ObservableProperty(Property):
"""Property for holding Cyber Observable Objects.
"""
def clean(self, value):
try:
@ -38,7 +40,7 @@ class ObservableProperty(Property):
class ExtensionsProperty(DictionaryProperty):
""" Property for representing extensions on Observable objects
"""Property for representing extensions on Observable objects.
"""
def __init__(self, enclosing_type=None, required=False):
@ -832,16 +834,15 @@ def _register_observable(new_observable):
def CustomObservable(type='x-custom-observable', properties=None):
"""Custom STIX Cyber Observable type decorator
"""Custom STIX Cyber Observable Object type decorator.
Example 1:
@CustomObservable('x-custom-observable', [
('property1', StringProperty(required=True)),
('property2', IntegerProperty()),
])
class MyNewObservableType():
pass
Example:
>>> @CustomObservable('x-custom-observable', [
... ('property1', StringProperty(required=True)),
... ('property2', IntegerProperty()),
... ])
... class MyNewObservableType():
... pass
"""
def custom_builder(cls):
@ -871,7 +872,14 @@ def CustomObservable(type='x-custom-observable', properties=None):
def __init__(self, **kwargs):
_Observable.__init__(self, **kwargs)
cls.__init__(self, **kwargs)
try:
cls.__init__(self, **kwargs)
except (AttributeError, TypeError) as e:
# Don't accidentally catch errors raised in a custom __init__()
if ("has no attribute '__init__'" in str(e) or
str(e) == "object.__init__() takes no parameters"):
return
raise e
_register_observable(_Custom)
return _Custom
@ -901,7 +909,7 @@ def _register_extension(observable, new_extension):
def CustomExtension(observable=None, type='x-custom-observable', properties=None):
"""Decorator for custom extensions to STIX Cyber Observables
"""Decorator for custom extensions to STIX Cyber Observables.
"""
if not observable or not issubclass(observable, _Observable):
@ -916,14 +924,21 @@ def CustomExtension(observable=None, type='x-custom-observable', properties=None
'extensions': ExtensionsProperty(enclosing_type=_type),
}
if not isinstance(properties, dict):
if not isinstance(properties, dict) or not properties:
raise ValueError("'properties' must be a dict!")
_properties.update(properties)
def __init__(self, **kwargs):
_Extension.__init__(self, **kwargs)
cls.__init__(self, **kwargs)
try:
cls.__init__(self, **kwargs)
except (AttributeError, TypeError) as e:
# Don't accidentally catch errors raised in a custom __init__()
if ("has no attribute '__init__'" in str(e) or
str(e) == "object.__init__() takes no parameters"):
return
raise e
_register_extension(observable, _Custom)
return _Custom

View File

@ -1,3 +1,6 @@
"""Classes to aid in working with the STIX 2 patterning language.
"""
import base64
import binascii
import re

View File

@ -1,3 +1,5 @@
"""Classes for representing properties of STIX Objects and Cyber Observables.
"""
import base64
import binascii
import collections
@ -17,43 +19,44 @@ class Property(object):
"""Represent a property of STIX data type.
Subclasses can define the following attributes as keyword arguments to
__init__():
``__init__()``.
- `required` - If `True`, the property must be provided when 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 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 defining both:
- a `clean()` function that checks if the value matches the fixed
value, and
- a `default()` function that returns the fixed value.
(Default: `None`)
Args:
required (bool): If ``True``, the property must be provided when 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 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 defining both:
Subclasses can also define the following functions.
- a ``clean()`` function that checks if the value matches the fixed
value, and
- a ``default()`` function that returns the fixed value.
- `def clean(self, value) -> any:`
- Return a value that is valid for this property. If `value` is not
Subclasses can also define the following functions:
- ``def clean(self, value) -> any:``
- Return a value that is valid for this property. If ``value`` is not
valid for this property, this will attempt to transform it first. If
`value` is not valid and no such transformation is possible, it should
``value`` is not valid and no such transformation is possible, it should
raise a ValueError.
- `def default(self):`
- ``def default(self):``
- provide a default value for this property.
- `default()` can return the special value `NOW` to use the current
- ``default()`` can return the special value ``NOW`` to use the current
time. This is useful when several timestamps in the same object need
to use the same default value, so calling now() for each property--
likely several microseconds apart-- does not work.
Subclasses can instead provide a lambda function for `default` as a keyword
argument. `clean` should not be provided as a lambda since lambdas cannot
Subclasses can instead provide a lambda function for ``default`` as a keyword
argument. ``clean`` should not be provided as a lambda since lambdas cannot
raise their own exceptions.
When instantiating Properties, `required` and `default` should not be used
together. `default` implies that the property is required in the specification
When instantiating Properties, ``required`` and ``default`` should not be used
together. ``default`` implies that the property is required in the specification
so this function will be used to supply a value if none is provided.
`required` means that the user must provide this; it is required in the
``required`` means that the user must provide this; it is required in the
specification and we can't or don't want to create a default value.
"""
@ -86,7 +89,7 @@ class ListProperty(Property):
def __init__(self, contained, **kwargs):
"""
Contained should be a function which returns an object from the value.
``contained`` should be a function which returns an object from the value.
"""
if inspect.isclass(contained) and issubclass(contained, Property):
# If it's a class and not an instance, instantiate it so that

View File

@ -6,7 +6,7 @@ import stix2
from .base import _STIXBase
from .common import ExternalReference, GranularMarking, KillChainPhase
from .markings import MarkingsMixin
from .markings import _MarkingsMixin
from .observables import ObservableProperty
from .properties import (BooleanProperty, EnumProperty, FloatProperty,
IDProperty, IntegerProperty, ListProperty,
@ -15,7 +15,7 @@ from .properties import (BooleanProperty, EnumProperty, FloatProperty,
from .utils import NOW
class STIXDomainObject(_STIXBase, MarkingsMixin):
class STIXDomainObject(_STIXBase, _MarkingsMixin):
pass
@ -402,30 +402,28 @@ class Vulnerability(STIXDomainObject):
def CustomObject(type='x-custom-type', properties=None):
"""Custom STIX Object type decorator
"""Custom STIX Object type decorator.
Example 1:
Example:
>>> @CustomObject('x-type-name', [
... ('property1', StringProperty(required=True)),
... ('property2', IntegerProperty()),
... ])
... class MyNewObjectType():
... pass
@CustomObject('x-type-name', [
('property1', StringProperty(required=True)),
('property2', IntegerProperty()),
])
class MyNewObjectType():
pass
Supply an ``__init__()`` function to add any special validations to the custom
type. Don't call ``super().__init__()`` though - doing so will cause an error.
Supply an __init__() function to add any special validations to the custom
type. Don't call super().__init__() though - doing so will cause an error.
Example 2:
@CustomObject('x-type-name', [
('property1', StringProperty(required=True)),
('property2', IntegerProperty()),
])
class MyNewObjectType():
def __init__(self, property2=None, **kwargs):
if property2 and property2 < 10:
raise ValueError("'property2' is too small.")
Example:
>>> @CustomObject('x-type-name', [
... ('property1', StringProperty(required=True)),
... ('property2', IntegerProperty()),
... ])
... class MyNewObjectType():
... def __init__(self, property2=None, **kwargs):
... if property2 and property2 < 10:
... raise ValueError("'property2' is too small.")
"""
def custom_builder(cls):
@ -463,7 +461,14 @@ def CustomObject(type='x-custom-type', properties=None):
def __init__(self, **kwargs):
_STIXBase.__init__(self, **kwargs)
cls.__init__(self, **kwargs)
try:
cls.__init__(self, **kwargs)
except (AttributeError, TypeError) as e:
# Don't accidentally catch errors raised in a custom __init__()
if ("has no attribute '__init__'" in str(e) or
str(e) == "object.__init__() takes no parameters"):
return
raise e
stix2._register_type(_Custom)
return _Custom

View File

@ -1,13 +1,14 @@
"""
Python STIX 2.0 Sources
"""Python STIX 2.0 Sources
Classes:
DataStore
DataSink
DataSource
CompositeDataSource
.. autosummary::
:toctree: sources
filesystem
filters
memory
taxii
|
"""
import uuid
@ -259,7 +260,8 @@ class CompositeDataSource(DataSource):
# for every configured Data Source, call its retrieve handler
for ds in self.data_sources:
data = ds.get(stix_id=stix_id, _composite_filters=all_filters)
all_data.append(data)
if data:
all_data.append(data)
# remove duplicate versions
if len(all_data) > 0:

View File

@ -1,12 +1,8 @@
"""
Python STIX 2.0 FileSystem Source/Sink
Classes:
FileSystemStore
FileSystemSink
FileSystemSource
TODO: Test everything
TODO:
Test everything
"""
import json
@ -134,7 +130,7 @@ class FileSystemSource(DataSource):
self._stix_dir = os.path.abspath(stix_dir)
if not os.path.exists(self._stix_dir):
print("Error: directory path for STIX data does not exist")
raise ValueError("directory path for STIX data does not exist: %s" % self._stix_dir)
@property
def stix_dir(self):
@ -183,7 +179,6 @@ class FileSystemSource(DataSource):
(list): of STIX objects that has the supplied STIX ID.
The STIX objects are loaded from their json files, parsed into
a python STIX objects and then returned
"""
return [self.get(stix_id=stix_id, _composite_filters=_composite_filters)]

View File

@ -1,9 +1,6 @@
"""
Filters for Python STIX 2.0 DataSources, DataSinks, DataStores
Classes:
Filter
"""
import collections
@ -117,7 +114,6 @@ def apply_common_filters(stix_objs, query):
Args:
stix_objs (list): list of STIX objects to apply the query to
query (set): set of filters (combined form complete query)
Returns:
@ -125,7 +121,6 @@ def apply_common_filters(stix_objs, query):
the query.
"""
for stix_obj in stix_objs:
clean = True
for filter_ in query:

View File

@ -1,18 +1,14 @@
"""
Python STIX 2.0 Memory Source/Sink
Classes:
MemoryStore
MemorySink
MemorySource
TODO:
Run through tests again, lot of changes.
TODO:
Use deduplicate() calls only when memory corpus is dirty (been added to)
can save a lot of time for successive queries
TODO: Run through tests again, lot of changes.
TODO: Use deduplicate() calls only when memory corpus is dirty (been added to)
can save a lot of time for successive queries
Notes:
Note:
Not worrying about STIX versioning. The in memory STIX data at anytime
will only hold one version of a STIX object. As such, when save() is called,
the single versions of all the STIX objects are what is written to file.

View File

@ -1,12 +1,8 @@
"""
Python STIX 2.0 TAXII Source/Sink
Classes:
TAXIICollectionStore
TAXIICollectionSink
TAXIICollectionSource
TODO: Test everything
TODO:
Test everything
"""
@ -121,10 +117,9 @@ class TAXIICollectionSource(DataSource):
if _composite_filters:
query.update(_composite_filters)
# separate taxii query terms (can be done remotely)
taxii_filters = self._parse_taxii_filters(query)
stix_objs = self.collection.get_object(stix_id, taxii_filters)["objects"]
# dont extract TAXII filters from query (to send to TAXII endpoint)
# as directly retrieveing a STIX object by ID
stix_objs = self.collection.get_object(stix_id)["objects"]
stix_obj = list(apply_common_filters(stix_objs, query))
@ -215,7 +210,7 @@ class TAXIICollectionSource(DataSource):
def _parse_taxii_filters(self, query):
"""Parse out TAXII filters that the TAXII server can filter on.
Notes:
Note:
For instance - "?match[type]=indicator,sighting" should be in a
query dict as follows:

View File

@ -4,14 +4,14 @@ from collections import OrderedDict
from .base import _STIXBase
from .common import ExternalReference, GranularMarking
from .markings import MarkingsMixin
from .markings import _MarkingsMixin
from .properties import (BooleanProperty, IDProperty, IntegerProperty,
ListProperty, ReferenceProperty, StringProperty,
TimestampProperty, TypeProperty)
from .utils import NOW
class STIXRelationshipObject(_STIXBase, MarkingsMixin):
class STIXRelationshipObject(_STIXBase, _MarkingsMixin):
pass

View File

@ -104,6 +104,26 @@ def test_custom_object_type():
assert "'property2' is too small." in str(excinfo.value)
def test_custom_object_no_init():
@stix2.sdo.CustomObject('x-new-obj', [
('property1', stix2.properties.StringProperty(required=True)),
])
class NewObj():
pass
no = NewObj(property1='something')
assert no.property1 == 'something'
@stix2.sdo.CustomObject('x-new-obj2', [
('property1', stix2.properties.StringProperty(required=True)),
])
class NewObj2(object):
pass
no2 = NewObj2(property1='something')
assert no2.property1 == 'something'
def test_parse_custom_object_type():
nt_string = """{
"type": "x-new-type",
@ -153,6 +173,26 @@ def test_custom_observable_object():
assert "'property2' is too small." in str(excinfo.value)
def test_custom_observable_object_no_init():
@stix2.observables.CustomObservable('x-new-observable', [
('property1', stix2.properties.StringProperty()),
])
class NewObs():
pass
no = NewObs(property1='something')
assert no.property1 == 'something'
@stix2.observables.CustomObservable('x-new-obs2', [
('property1', stix2.properties.StringProperty()),
])
class NewObs2(object):
pass
no2 = NewObs2(property1='something')
assert no2.property1 == 'something'
def test_custom_observable_object_invalid_ref_property():
with pytest.raises(ValueError) as excinfo:
@stix2.observables.CustomObservable('x-new-obs', [
@ -366,12 +406,40 @@ def test_custom_extension_invalid_observable():
def test_custom_extension_no_properties():
with pytest.raises(ValueError) as excinfo:
@stix2.observables.CustomExtension(stix2.DomainName, 'x-new-ext', None)
@stix2.observables.CustomExtension(stix2.DomainName, 'x-new-ext2', None)
class BarExtension():
pass
assert "'properties' must be a dict!" in str(excinfo.value)
def test_custom_extension_empty_properties():
with pytest.raises(ValueError) as excinfo:
@stix2.observables.CustomExtension(stix2.DomainName, 'x-new-ext2', {})
class BarExtension():
pass
assert "'properties' must be a dict!" in str(excinfo.value)
def test_custom_extension_no_init():
@stix2.observables.CustomExtension(stix2.DomainName, 'x-new-extension', {
'property1': stix2.properties.StringProperty(required=True),
})
class NewExt():
pass
ne = NewExt(property1="foobar")
assert ne.property1 == "foobar"
@stix2.observables.CustomExtension(stix2.DomainName, 'x-new-ext2', {
'property1': stix2.properties.StringProperty(required=True),
})
class NewExt2(object):
pass
ne2 = NewExt2(property1="foobar")
assert ne2.property1 == "foobar"
def test_parse_observable_with_custom_extension():
input_str = """{
"type": "domain-name",

View File

@ -48,8 +48,6 @@ def test_indicator_with_all_required_properties():
assert str(ind) == EXPECTED_INDICATOR
rep = re.sub(r"(\[|=| )u('|\"|\\\'|\\\")", r"\g<1>\g<2>", repr(ind))
print(rep)
print(EXPECTED_INDICATOR_REPR)
assert rep == EXPECTED_INDICATOR_REPR

View File

@ -62,16 +62,21 @@ def deduplicate(stix_obj_list):
def get_timestamp():
"""Return a STIX timestamp of the current date and time."""
return STIXdatetime.now(tz=pytz.UTC)
def format_datetime(dttm):
# 1. Convert to timezone-aware
# 2. Convert to UTC
# 3. Format in ISO format
# 4. Ensure correct precision
# 4a. Add subsecond value if non-zero and precision not defined
# 5. Add "Z"
"""Convert a datetime object into a valid STIX timestamp string.
1. Convert to timezone-aware
2. Convert to UTC
3. Format in ISO format
4. Ensure correct precision
a. Add subsecond value if non-zero and precision not defined
5. Add "Z"
"""
if dttm.tzinfo is None or dttm.tzinfo.utcoffset(dttm) is None:
# dttm is timezone-naive; assume UTC
@ -91,6 +96,8 @@ def format_datetime(dttm):
def parse_into_datetime(value, precision=None):
"""Parse a value into a valid STIX timestamp object.
"""
if isinstance(value, dt.date):
if hasattr(value, 'hour'):
ts = value
@ -130,6 +137,7 @@ def parse_into_datetime(value, precision=None):
def get_dict(data):
"""Return data as a dictionary.
Input can be a dictionary, string, or file-like object.
"""
@ -152,7 +160,7 @@ def get_dict(data):
def find_property_index(obj, properties, tuple_to_find):
"""Recursively find the property in the object model, return the index
according to the _properties OrderedDict. If its a list look for
according to the _properties OrderedDict. If it's a list look for
individual objects.
"""
from .base import _STIXBase
@ -187,7 +195,7 @@ def find_property_index(obj, properties, tuple_to_find):
def new_version(data, **kwargs):
"""Create a new version of a STIX object, by modifying properties and
updating the `modified` property.
updating the ``modified`` property.
"""
if not isinstance(data, Mapping):
@ -224,6 +232,11 @@ def new_version(data, **kwargs):
def revoke(data):
"""Revoke a STIX object.
Returns:
A new version of the object with ``revoked`` set to ``True``.
"""
if not isinstance(data, Mapping):
raise ValueError('cannot revoke object of this type! Try a dictionary '
'or instance of an SDO or SRO class.')

View File

@ -1 +1 @@
__version__ = "0.2.0"
__version__ = "0.3.0"