diff --git a/.gitignore b/.gitignore index 3b953e1..395676e 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,7 @@ coverage.xml # Sphinx documentation docs/_build/ +.ipynb_checkpoints # PyBuilder target/ diff --git a/README.rst b/README.rst index d4762c1..c78923b 100644 --- a/README.rst +++ b/README.rst @@ -28,11 +28,9 @@ Install with `pip `__: 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/ `__. Governance ---------- diff --git a/docs/_templates/autosummary/module.rst b/docs/_templates/autosummary/module.rst new file mode 100644 index 0000000..37c15c8 --- /dev/null +++ b/docs/_templates/autosummary/module.rst @@ -0,0 +1,5 @@ +{{ name }} +{{ underline }} + +.. automodule:: {{ fullname }} + :members: diff --git a/docs/api/markings/stix2.markings.granular_markings.rst b/docs/api/markings/stix2.markings.granular_markings.rst new file mode 100644 index 0000000..b4a7160 --- /dev/null +++ b/docs/api/markings/stix2.markings.granular_markings.rst @@ -0,0 +1,5 @@ +granular_markings +================================ + +.. automodule:: stix2.markings.granular_markings + :members: \ No newline at end of file diff --git a/docs/api/markings/stix2.markings.object_markings.rst b/docs/api/markings/stix2.markings.object_markings.rst new file mode 100644 index 0000000..d861c87 --- /dev/null +++ b/docs/api/markings/stix2.markings.object_markings.rst @@ -0,0 +1,5 @@ +object_markings +============================== + +.. automodule:: stix2.markings.object_markings + :members: \ No newline at end of file diff --git a/docs/api/markings/stix2.markings.utils.rst b/docs/api/markings/stix2.markings.utils.rst new file mode 100644 index 0000000..ee59b6c --- /dev/null +++ b/docs/api/markings/stix2.markings.utils.rst @@ -0,0 +1,5 @@ +utils +==================== + +.. automodule:: stix2.markings.utils + :members: \ No newline at end of file diff --git a/docs/api/sources/stix2.sources.filesystem.rst b/docs/api/sources/stix2.sources.filesystem.rst new file mode 100644 index 0000000..ca0cfce --- /dev/null +++ b/docs/api/sources/stix2.sources.filesystem.rst @@ -0,0 +1,5 @@ +filesystem +======================== + +.. automodule:: stix2.sources.filesystem + :members: \ No newline at end of file diff --git a/docs/api/sources/stix2.sources.filters.rst b/docs/api/sources/stix2.sources.filters.rst new file mode 100644 index 0000000..43dea51 --- /dev/null +++ b/docs/api/sources/stix2.sources.filters.rst @@ -0,0 +1,5 @@ +filters +===================== + +.. automodule:: stix2.sources.filters + :members: \ No newline at end of file diff --git a/docs/api/sources/stix2.sources.memory.rst b/docs/api/sources/stix2.sources.memory.rst new file mode 100644 index 0000000..1e70f2e --- /dev/null +++ b/docs/api/sources/stix2.sources.memory.rst @@ -0,0 +1,5 @@ +memory +==================== + +.. automodule:: stix2.sources.memory + :members: \ No newline at end of file diff --git a/docs/api/sources/stix2.sources.taxii.rst b/docs/api/sources/stix2.sources.taxii.rst new file mode 100644 index 0000000..42303fe --- /dev/null +++ b/docs/api/sources/stix2.sources.taxii.rst @@ -0,0 +1,5 @@ +taxii +=================== + +.. automodule:: stix2.sources.taxii + :members: \ No newline at end of file diff --git a/docs/api/stix2.common.rst b/docs/api/stix2.common.rst new file mode 100644 index 0000000..9e90b03 --- /dev/null +++ b/docs/api/stix2.common.rst @@ -0,0 +1,5 @@ +common +============ + +.. automodule:: stix2.common + :members: \ No newline at end of file diff --git a/docs/api/stix2.core.rst b/docs/api/stix2.core.rst new file mode 100644 index 0000000..f0e98d4 --- /dev/null +++ b/docs/api/stix2.core.rst @@ -0,0 +1,5 @@ +core +========== + +.. automodule:: stix2.core + :members: \ No newline at end of file diff --git a/docs/api/stix2.environment.rst b/docs/api/stix2.environment.rst new file mode 100644 index 0000000..fb5c7b7 --- /dev/null +++ b/docs/api/stix2.environment.rst @@ -0,0 +1,5 @@ +environment +================= + +.. automodule:: stix2.environment + :members: \ No newline at end of file diff --git a/docs/api/stix2.exceptions.rst b/docs/api/stix2.exceptions.rst new file mode 100644 index 0000000..a8d498e --- /dev/null +++ b/docs/api/stix2.exceptions.rst @@ -0,0 +1,5 @@ +exceptions +================ + +.. automodule:: stix2.exceptions + :members: \ No newline at end of file diff --git a/docs/api/stix2.markings.rst b/docs/api/stix2.markings.rst new file mode 100644 index 0000000..9819fe7 --- /dev/null +++ b/docs/api/stix2.markings.rst @@ -0,0 +1,5 @@ +markings +============== + +.. automodule:: stix2.markings + :members: \ No newline at end of file diff --git a/docs/api/stix2.observables.rst b/docs/api/stix2.observables.rst new file mode 100644 index 0000000..2d19996 --- /dev/null +++ b/docs/api/stix2.observables.rst @@ -0,0 +1,5 @@ +observables +================= + +.. automodule:: stix2.observables + :members: \ No newline at end of file diff --git a/docs/api/stix2.patterns.rst b/docs/api/stix2.patterns.rst new file mode 100644 index 0000000..ec7b42c --- /dev/null +++ b/docs/api/stix2.patterns.rst @@ -0,0 +1,5 @@ +patterns +============== + +.. automodule:: stix2.patterns + :members: \ No newline at end of file diff --git a/docs/api/stix2.properties.rst b/docs/api/stix2.properties.rst new file mode 100644 index 0000000..c3db9ff --- /dev/null +++ b/docs/api/stix2.properties.rst @@ -0,0 +1,5 @@ +properties +================ + +.. automodule:: stix2.properties + :members: \ No newline at end of file diff --git a/docs/api/stix2.sdo.rst b/docs/api/stix2.sdo.rst new file mode 100644 index 0000000..9448ff4 --- /dev/null +++ b/docs/api/stix2.sdo.rst @@ -0,0 +1,5 @@ +sdo +========= + +.. automodule:: stix2.sdo + :members: \ No newline at end of file diff --git a/docs/api/stix2.sources.rst b/docs/api/stix2.sources.rst new file mode 100644 index 0000000..aaf9f89 --- /dev/null +++ b/docs/api/stix2.sources.rst @@ -0,0 +1,5 @@ +sources +============= + +.. automodule:: stix2.sources + :members: \ No newline at end of file diff --git a/docs/api/stix2.sro.rst b/docs/api/stix2.sro.rst new file mode 100644 index 0000000..a63af76 --- /dev/null +++ b/docs/api/stix2.sro.rst @@ -0,0 +1,5 @@ +sro +========= + +.. automodule:: stix2.sro + :members: \ No newline at end of file diff --git a/docs/api/stix2.utils.rst b/docs/api/stix2.utils.rst new file mode 100644 index 0000000..4091fb5 --- /dev/null +++ b/docs/api/stix2.utils.rst @@ -0,0 +1,5 @@ +utils +=========== + +.. automodule:: stix2.utils + :members: \ No newline at end of file diff --git a/docs/api_ref.rst b/docs/api_ref.rst new file mode 100644 index 0000000..11bf278 --- /dev/null +++ b/docs/api_ref.rst @@ -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 diff --git a/docs/conf.py b/docs/conf.py index e863486..b241fe5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -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' @@ -13,7 +32,7 @@ version = '0.2.0' release = '0.2.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 diff --git a/docs/guide.rst b/docs/guide.rst new file mode 100644 index 0000000..80d2fb3 --- /dev/null +++ b/docs/guide.rst @@ -0,0 +1,7 @@ +User's Guide +============ + +.. toctree:: + :glob: + + guide/* diff --git a/docs/guide/creating.ipynb b/docs/guide/creating.ipynb new file mode 100644 index 0000000..6cfea7f --- /dev/null +++ b/docs/guide/creating.ipynb @@ -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('{}'.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": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "id": "indicator--dbcbd659-c927-4f9a-994f-0a2632274394",\n",
+       "    "created": "2017-09-26T23:33:39.829Z",\n",
+       "    "modified": "2017-09-26T23:33:39.829Z",\n",
+       "    "labels": [\n",
+       "        "malicious-activity"\n",
+       "    ],\n",
+       "    "name": "File hash for malware variant",\n",
+       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+       "    "valid_from": "2017-09-26T23:33:39.829952Z"\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "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": [ + "
{\n",
+       "    "type": "malware",\n",
+       "    "id": "malware--d7fd675d-94eb-4d95-b0bc-b3c5e28e8ed2",\n",
+       "    "created": "2017-09-26T23:33:56.908Z",\n",
+       "    "modified": "2017-09-26T23:33:56.908Z",\n",
+       "    "name": "Poison Ivy",\n",
+       "    "labels": [\n",
+       "        "remote-access-trojan"\n",
+       "    ]\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "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": [ + "
{\n",
+       "    "type": "relationship",\n",
+       "    "id": "relationship--637aa3b1-d4b8-4bc4-85e7-77cc82b198a3",\n",
+       "    "created": "2017-09-26T23:34:01.765Z",\n",
+       "    "modified": "2017-09-26T23:34:01.765Z",\n",
+       "    "relationship_type": "indicates",\n",
+       "    "source_ref": "indicator--dbcbd659-c927-4f9a-994f-0a2632274394",\n",
+       "    "target_ref": "malware--d7fd675d-94eb-4d95-b0bc-b3c5e28e8ed2"\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "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": [ + "
{\n",
+       "    "type": "relationship",\n",
+       "    "id": "relationship--70fe77c2-ab00-4181-a2dc-fe5567d971ca",\n",
+       "    "created": "2017-09-26T23:34:03.923Z",\n",
+       "    "modified": "2017-09-26T23:34:03.923Z",\n",
+       "    "relationship_type": "indicates",\n",
+       "    "source_ref": "indicator--dbcbd659-c927-4f9a-994f-0a2632274394",\n",
+       "    "target_ref": "malware--d7fd675d-94eb-4d95-b0bc-b3c5e28e8ed2"\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "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": [ + "
{\n",
+       "    "type": "bundle",\n",
+       "    "id": "bundle--2536c43d-c874-418e-886c-20a22120d8cb",\n",
+       "    "spec_version": "2.0",\n",
+       "    "objects": [\n",
+       "        {\n",
+       "            "type": "indicator",\n",
+       "            "id": "indicator--dbcbd659-c927-4f9a-994f-0a2632274394",\n",
+       "            "created": "2017-09-26T23:33:39.829Z",\n",
+       "            "modified": "2017-09-26T23:33:39.829Z",\n",
+       "            "labels": [\n",
+       "                "malicious-activity"\n",
+       "            ],\n",
+       "            "name": "File hash for malware variant",\n",
+       "            "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+       "            "valid_from": "2017-09-26T23:33:39.829952Z"\n",
+       "        },\n",
+       "        {\n",
+       "            "type": "malware",\n",
+       "            "id": "malware--d7fd675d-94eb-4d95-b0bc-b3c5e28e8ed2",\n",
+       "            "created": "2017-09-26T23:33:56.908Z",\n",
+       "            "modified": "2017-09-26T23:33:56.908Z",\n",
+       "            "name": "Poison Ivy",\n",
+       "            "labels": [\n",
+       "                "remote-access-trojan"\n",
+       "            ]\n",
+       "        },\n",
+       "        {\n",
+       "            "type": "relationship",\n",
+       "            "id": "relationship--637aa3b1-d4b8-4bc4-85e7-77cc82b198a3",\n",
+       "            "created": "2017-09-26T23:34:01.765Z",\n",
+       "            "modified": "2017-09-26T23:34:01.765Z",\n",
+       "            "relationship_type": "indicates",\n",
+       "            "source_ref": "indicator--dbcbd659-c927-4f9a-994f-0a2632274394",\n",
+       "            "target_ref": "malware--d7fd675d-94eb-4d95-b0bc-b3c5e28e8ed2"\n",
+       "        }\n",
+       "    ]\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "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 +} diff --git a/docs/guide/custom.ipynb b/docs/guide/custom.ipynb new file mode 100644 index 0000000..2254fa8 --- /dev/null +++ b/docs/guide/custom.ipynb @@ -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('{}'.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": [ + "
{\n",
+       "    "x_foo": "bar",\n",
+       "    "type": "identity",\n",
+       "    "id": "identity--8d7f0697-e589-4e3b-aa57-cae798d2d138",\n",
+       "    "created": "2017-09-26T21:02:19.465Z",\n",
+       "    "modified": "2017-09-26T21:02:19.465Z",\n",
+       "    "name": "John Smith",\n",
+       "    "identity_class": "individual"\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "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": [ + "
{\n",
+       "    "x_foo": "bar",\n",
+       "    "type": "identity",\n",
+       "    "id": "identity--1e8188eb-245f-400b-839d-7f612169c514",\n",
+       "    "created": "2017-09-26T21:02:22.708Z",\n",
+       "    "modified": "2017-09-26T21:02:22.708Z",\n",
+       "    "name": "John Smith",\n",
+       "    "identity_class": "individual"\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "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": [ + "
{\n",
+       "    "type": "x-animal",\n",
+       "    "id": "x-animal--caebdf17-9d2a-4c84-8864-7406326618f0",\n",
+       "    "created": "2017-09-26T21:02:34.724Z",\n",
+       "    "modified": "2017-09-26T21:02:34.724Z",\n",
+       "    "species": "lion",\n",
+       "    "animal_class": "mammal"\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "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": [ + "
{\n",
+       "    "type": "x-new-observable",\n",
+       "    "a_property": "something",\n",
+       "    "property_2": 10\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "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": [ + "
{\n",
+       "    "property1": "something",\n",
+       "    "property2": 10\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "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 +} diff --git a/docs/guide/datastore.ipynb b/docs/guide/datastore.ipynb new file mode 100644 index 0000000..f6d360b --- /dev/null +++ b/docs/guide/datastore.ipynb @@ -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('{}'.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 +} diff --git a/docs/guide/environment.ipynb b/docs/guide/environment.ipynb new file mode 100644 index 0000000..a9184a1 --- /dev/null +++ b/docs/guide/environment.ipynb @@ -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('{}'.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": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "id": "indicator--01234567-89ab-cdef-0123-456789abcdef",\n",
+       "    "created": "2017-10-02T13:20:39.373Z",\n",
+       "    "modified": "2017-10-02T13:20:39.373Z",\n",
+       "    "labels": [\n",
+       "        "malicious-activity"\n",
+       "    ],\n",
+       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+       "    "valid_from": "2017-10-02T13:20:39.3737Z"\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "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": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "id": "indicator--c92ad60d-449d-4adf-86b3-4e5951a8f480",\n",
+       "    "created_by_ref": "identity--311b2d2d-f010-5473-83ec-1edf84858f4c",\n",
+       "    "created": "2017-10-02T13:23:00.607Z",\n",
+       "    "modified": "2017-10-02T13:23:00.607Z",\n",
+       "    "labels": [\n",
+       "        "malicious-activity"\n",
+       "    ],\n",
+       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+       "    "valid_from": "2017-10-02T13:23:00.607216Z"\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "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": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "id": "indicator--ae206b9f-8723-4fcf-beb7-8b1b9a2570ab",\n",
+       "    "created": "2017-09-25T18:07:46.255Z",\n",
+       "    "modified": "2017-09-25T18:07:46.255Z",\n",
+       "    "labels": [\n",
+       "        "malicious-activity"\n",
+       "    ],\n",
+       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+       "    "valid_from": "2017-10-02T13:23:05.790562Z"\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "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": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "id": "indicator--a8e2be68-b496-463f-9ff4-f620046e7cf2",\n",
+       "    "created_by_ref": "identity--962cabe5-f7f3-438a-9169-585a8c971d12",\n",
+       "    "created": "2017-09-25T18:07:46.255Z",\n",
+       "    "modified": "2017-09-25T18:07:46.255Z",\n",
+       "    "labels": [\n",
+       "        "malicious-activity"\n",
+       "    ],\n",
+       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+       "    "valid_from": "2017-10-02T13:23:08.32424Z"\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "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": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "id": "indicator--89ba04ea-cce9-47a3-acd3-b6379ce51581",\n",
+       "    "created_by_ref": "identity--311b2d2d-f010-5473-83ec-1edf84858f4c",\n",
+       "    "created": "2017-10-02T13:23:29.629Z",\n",
+       "    "modified": "2017-10-02T13:23:29.629Z",\n",
+       "    "labels": [\n",
+       "        "malicious-activity"\n",
+       "    ],\n",
+       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+       "    "valid_from": "2017-10-02T13:23:29.629857Z"\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "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 +} diff --git a/docs/guide/filesystem.ipynb b/docs/guide/filesystem.ipynb new file mode 100644 index 0000000..c2e21b4 --- /dev/null +++ b/docs/guide/filesystem.ipynb @@ -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('{}'.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 +} diff --git a/docs/guide/markings.ipynb b/docs/guide/markings.ipynb new file mode 100644 index 0000000..cb8f762 --- /dev/null +++ b/docs/guide/markings.ipynb @@ -0,0 +1,1332 @@ +{ + "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('{}'.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": [ + "## Data Markings" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Creating Objects With Data Markings\n", + "\n", + "To create an object with a (predefined) TLP marking to an object, just provide it as a keyword argument to the constructor. The TLP markings can easily be imported from python-stix2." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "id": "indicator--409a0b15-1108-4251-8aee-a08995976561",\n",
+       "    "created": "2017-10-04T14:42:54.685Z",\n",
+       "    "modified": "2017-10-04T14:42:54.685Z",\n",
+       "    "labels": [\n",
+       "        "malicious-activity"\n",
+       "    ],\n",
+       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+       "    "valid_from": "2017-10-04T14:42:54.685184Z",\n",
+       "    "object_marking_refs": [\n",
+       "        "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82"\n",
+       "    ]\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from stix2 import Indicator, TLP_AMBER\n", + "\n", + "indicator = Indicator(labels=[\"malicious-activity\"],\n", + " pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\",\n", + " object_marking_refs=TLP_AMBER)\n", + "print(indicator)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you’re creating your own marking (for example, a ``Statement`` marking), first create the statement marking:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
{\n",
+       "    "type": "marking-definition",\n",
+       "    "id": "marking-definition--030bb5c6-c5eb-4e9c-8e7a-b9aab08ded53",\n",
+       "    "created": "2017-10-04T14:43:04.090873Z",\n",
+       "    "definition_type": "statement",\n",
+       "    "definition": {\n",
+       "        "statement": "Copyright 2017, Example Corp"\n",
+       "    }\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from stix2 import MarkingDefinition, StatementMarking\n", + "\n", + "marking_definition = MarkingDefinition( \n", + " definition_type=\"statement\", \n", + " definition=StatementMarking(statement=\"Copyright 2017, Example Corp\")\n", + ")\n", + "print(marking_definition)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then you can add it to an object as it’s being created (passing either full object or the the ID as a keyword argument, like with relationships)." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "id": "indicator--526cda4e-6745-4cd6-852f-0750c6a79784",\n",
+       "    "created": "2017-10-04T14:43:09.586Z",\n",
+       "    "modified": "2017-10-04T14:43:09.586Z",\n",
+       "    "labels": [\n",
+       "        "malicious-activity"\n",
+       "    ],\n",
+       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+       "    "valid_from": "2017-10-04T14:43:09.586133Z",\n",
+       "    "object_marking_refs": [\n",
+       "        "marking-definition--030bb5c6-c5eb-4e9c-8e7a-b9aab08ded53"\n",
+       "    ]\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "indicator2 = Indicator(labels=[\"malicious-activity\"],\n", + " pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\",\n", + " object_marking_refs=marking_definition)\n", + "print(indicator2)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "id": "indicator--1505b789-fcd2-48ee-bea9-3b20627a4abd",\n",
+       "    "created": "2017-10-04T14:43:20.049Z",\n",
+       "    "modified": "2017-10-04T14:43:20.049Z",\n",
+       "    "labels": [\n",
+       "        "malicious-activity"\n",
+       "    ],\n",
+       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+       "    "valid_from": "2017-10-04T14:43:20.049166Z",\n",
+       "    "object_marking_refs": [\n",
+       "        "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82"\n",
+       "    ]\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "indicator3 = Indicator(labels=[\"malicious-activity\"],\n", + " pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\",\n", + " object_marking_refs=\"marking-definition--f88d31f6-486f-44da-b317-01333bde0b82\")\n", + "print(indicator3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Granular markings work in the same way, except you also need to provide a full granular-marking object (including the selector)." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
{\n",
+       "    "type": "malware",\n",
+       "    "id": "malware--9f8970eb-b398-41b6-b8c8-8a607ad3a2c5",\n",
+       "    "created": "2017-10-04T14:43:26.129Z",\n",
+       "    "modified": "2017-10-04T14:43:26.129Z",\n",
+       "    "name": "Poison Ivy",\n",
+       "    "description": "A ransomware related to ...",\n",
+       "    "labels": [\n",
+       "        "remote-access-trojan"\n",
+       "    ],\n",
+       "    "granular_markings": [\n",
+       "        {\n",
+       "            "marking_ref": "marking-definition--030bb5c6-c5eb-4e9c-8e7a-b9aab08ded53",\n",
+       "            "selectors": [\n",
+       "                "description"\n",
+       "            ]\n",
+       "        },\n",
+       "        {\n",
+       "            "marking_ref": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9",\n",
+       "            "selectors": [\n",
+       "                "name"\n",
+       "            ]\n",
+       "        }\n",
+       "    ]\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from stix2 import Malware, TLP_WHITE\n", + "\n", + "malware = Malware(name=\"Poison Ivy\",\n", + " labels=['remote-access-trojan'],\n", + " description=\"A ransomware related to ...\",\n", + " granular_markings=[\n", + " {\n", + " \"selectors\": [\"description\"],\n", + " \"marking_ref\": marking_definition\n", + " },\n", + " {\n", + " \"selectors\": [\"name\"],\n", + " \"marking_ref\": TLP_WHITE\n", + " }\n", + " ])\n", + "print(malware)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Make sure that the selector is a field that exists and is populated on the object, otherwise this will cause an error:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "ename": "InvalidSelectorError", + "evalue": "Selector title in Malware is not valid!", + "output_type": "error", + "traceback": [ + "\u001b[0;31mInvalidSelectorError\u001b[0m\u001b[0;31m:\u001b[0m Selector title in Malware is not valid!\n" + ] + } + ], + "source": [ + "Malware(name=\"Poison Ivy\",\n", + " labels=['remote-access-trojan'],\n", + " description=\"A ransomware related to ...\",\n", + " granular_markings=[\n", + " {\n", + " \"selectors\": [\"title\"],\n", + " \"marking_ref\": marking_definition\n", + " }\n", + " ])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Adding Data Markings To Existing Objects" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Both object markings and granular markings can also be added to STIX objects which have already been created.\n", + "\n", + "**Note**: Doing so will create a new version of the object (note the updated ``modified`` time)." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "id": "indicator--409a0b15-1108-4251-8aee-a08995976561",\n",
+       "    "created": "2017-10-04T14:42:54.685Z",\n",
+       "    "modified": "2017-10-04T15:03:46.599Z",\n",
+       "    "labels": [\n",
+       "        "malicious-activity"\n",
+       "    ],\n",
+       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+       "    "valid_from": "2017-10-04T14:42:54.685184Z",\n",
+       "    "object_marking_refs": [\n",
+       "        "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82",\n",
+       "        "marking-definition--030bb5c6-c5eb-4e9c-8e7a-b9aab08ded53"\n",
+       "    ]\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "indicator4 = indicator.add_markings(marking_definition)\n", + "print(indicator4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can also remove specific markings from STIX objects. This will also create a new version of the object." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "id": "indicator--409a0b15-1108-4251-8aee-a08995976561",\n",
+       "    "created": "2017-10-04T14:42:54.685Z",\n",
+       "    "modified": "2017-10-04T15:03:54.290Z",\n",
+       "    "labels": [\n",
+       "        "malicious-activity"\n",
+       "    ],\n",
+       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+       "    "valid_from": "2017-10-04T14:42:54.685184Z",\n",
+       "    "object_marking_refs": [\n",
+       "        "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82"\n",
+       "    ]\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "indicator5 = indicator4.remove_markings(marking_definition)\n", + "print(indicator5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The markings on an object can be replaced with a different set of markings:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "id": "indicator--409a0b15-1108-4251-8aee-a08995976561",\n",
+       "    "created": "2017-10-04T14:42:54.685Z",\n",
+       "    "modified": "2017-10-04T15:04:04.218Z",\n",
+       "    "labels": [\n",
+       "        "malicious-activity"\n",
+       "    ],\n",
+       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+       "    "valid_from": "2017-10-04T14:42:54.685184Z",\n",
+       "    "object_marking_refs": [\n",
+       "        "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da",\n",
+       "        "marking-definition--030bb5c6-c5eb-4e9c-8e7a-b9aab08ded53"\n",
+       "    ]\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from stix2 import TLP_GREEN\n", + "\n", + "indicator6 = indicator5.set_markings([TLP_GREEN, marking_definition])\n", + "print(indicator6)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "STIX objects can also be cleared of all markings:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "id": "indicator--409a0b15-1108-4251-8aee-a08995976561",\n",
+       "    "created": "2017-10-04T14:42:54.685Z",\n",
+       "    "modified": "2017-10-04T14:54:39.331Z",\n",
+       "    "labels": [\n",
+       "        "malicious-activity"\n",
+       "    ],\n",
+       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+       "    "valid_from": "2017-10-04T14:42:54.685184Z"\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "indicator7 = indicator5.clear_markings()\n", + "print(indicator7)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "All of these functions can be used for granular markings by passing in a list of selectors. Note that they will create new versions of the objects." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Evaluating Data Markings\n", + "\n", + "You can get a list of the object markings on a STIX object:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da',\n", + " 'marking-definition--030bb5c6-c5eb-4e9c-8e7a-b9aab08ded53']" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "indicator6.get_markings()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To get a list of the granular markings on an object, pass the object and a list of selectors to ``get_markings``:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9']" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "malware.get_markings('name')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can also call ``get_markings()`` as a method on the STIX object." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9']" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "malware.get_markings('name')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, you may also check if an object is marked by a specific markings. Again, for granular markings, pass in the selector or list of selectors." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "indicator.is_marked(TLP_AMBER.id)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "malware.is_marked(TLP_WHITE.id, 'name')" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "malware.is_marked(TLP_WHITE.id, 'description')" + ] + } + ], + "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 +} diff --git a/docs/guide/memory.ipynb b/docs/guide/memory.ipynb new file mode 100644 index 0000000..570425e --- /dev/null +++ b/docs/guide/memory.ipynb @@ -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('{}'.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 +} diff --git a/docs/guide/parsing.ipynb b/docs/guide/parsing.ipynb new file mode 100644 index 0000000..e991e0c --- /dev/null +++ b/docs/guide/parsing.ipynb @@ -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('{}'.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 +} diff --git a/docs/guide/serializing.ipynb b/docs/guide/serializing.ipynb new file mode 100644 index 0000000..8fcc19d --- /dev/null +++ b/docs/guide/serializing.ipynb @@ -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('{}'.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": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "id": "indicator--81b0644d-5e9d-48fb-bb83-aabe77918305",\n",
+       "    "created": "2017-09-26T23:38:55.476Z",\n",
+       "    "modified": "2017-09-26T23:38:55.476Z",\n",
+       "    "labels": [\n",
+       "        "malicious-activity"\n",
+       "    ],\n",
+       "    "name": "File hash for malware variant",\n",
+       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+       "    "valid_from": "2017-09-26T23:38:55.476436Z"\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "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 +} diff --git a/docs/guide/taxii.ipynb b/docs/guide/taxii.ipynb new file mode 100644 index 0000000..2890659 --- /dev/null +++ b/docs/guide/taxii.ipynb @@ -0,0 +1,2542 @@ +{ + "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('{}'.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": [ + "## TAXIICollection\n", + "\n", + "The TAXIICollection suite contains **TAXIICollectionStore**, **TAXIICollectionSource**, and **TAXIICollectionSink**. **TAXIICollectionStore** for pushing and retrieving STIX content to local/remote TAXII Collection(s). **TAXIICollectionSource** for retrieving STIX content to local/remote TAXII Collection(s). **TAXIICollectionSink** for pushing STIX content to local/remote TAXII Collection(s). Each of the interfaces is designed to be binded to a Collection from the taxii2client library (taxii2client.Collection), where all **TAXIICollection** API calls will be executed through that Collection instance.\n", + "\n", + "A note on TAXII2 searching/filtering of STIX content. TAXII2 server implementations natively support searching on the STIX2 object properties: id, type and version; API requests made to TAXII2 can contain filter arguments for those 3 properties. However, the **TAXIICollection** suite supports searching on all STIX2 common object properties (see **Filters** documentation for full listing). This works simply by augmenting the filtering that is done remotely at the TAXII2 server instance. **TAXIICollection** will seperate any supplied queries into TAXII supported filters and non-supported filters. During a **TAXIICollection** API call, TAXII2 supported filters get inserted into the TAXII2 server request (to be evaluated at the server). The rest of the filters are kept locally and then applied to the STIX2 content that is returned from the TAXII2 server, before being returned from the **TAXIICollection** API call. \n", + "\n", + "### TAXIICollection API\n", + "\n", + "### TAXIICollection Examples\n", + "\n", + "#### TAXIICollectionSource" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " \"type\": \"indicator\",\n", + " \"id\": \"indicator--fb2c0e55-52a0-423c-b544-8b09622cafc1\",\n", + " \"created\": \"2017-10-02T19:26:30.000Z\",\n", + " \"modified\": \"2017-10-02T19:26:30.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-02T19:26:30Z\",\n", + " \"kill_chain_phases\": [\n", + " {\n", + " \"kill_chain_name\": \"lockheed-martin-cyber-kill-chain\",\n", + " \"phase_name\": \"delivery\"\n", + " }\n", + " ]\n", + "}\n" + ] + } + ], + "source": [ + "from stix2 import TAXIICollectionSource\n", + "from taxii2client import Collection\n", + "\n", + "# establish TAXII2 Collection instance\n", + "collection = Collection(\"https://test.freetaxii.com:8000/api1/collections/9cfa669c-ee94-4ece-afd2-f8edac37d8fd/\")\n", + "# supply the TAXII2 collection to TAXIICollection\n", + "tc_source = TAXIICollectionSource(collection)\n", + "\n", + "#retrieve STIX object by id\n", + "stix_obj = tc_source.get(\"indicator--0f63229c-07a2-46dd-939d-312c7bf6d114\")\n", + "\n", + "#for visual purposes\n", + "print(stix_obj)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "indicators: 126\n", + "{\n", + " \"type\": \"indicator\",\n", + " \"id\": \"indicator--569b8969-bfce-4ab4-9a45-06ce78799a35\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '207.158.1.150' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--9c418633-9970-424e-8030-2c3dfa3105da\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '64.4.30.34' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--9d7cdfc1-94c3-49b5-b124-ebdce709fd99\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '216.152.67.22' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--37390a22-5d82-4ebc-9b90-7368a5efc8f7\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '69.16.172.34' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--30731d72-64b0-4851-bd97-c3d164d2fd2b\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '194.24.188.100' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--a4eb3524-992c-4b50-9729-99be3048625e\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '213.232.93.3' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--c00fb599-7e7b-4033-a6c2-d279212578a0\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '216.152.66.45' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--e7273b13-847c-4a69-8faf-08fc24af5ef0\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '89.16.176.16' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--b8d21867-c812-4ff9-866b-182a801b88ce\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '130.239.18.172' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--4c39b1a0-17f0-4cf1-9e48-250f0dd1f75c\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '140.211.166.4' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--8eeff049-f7da-45d9-89bb-713063baed2c\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '213.92.8.4' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--e3981158-1934-4236-8454-4dcfc27ac248\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '208.87.120.111' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--206c2a0c-149f-426f-a734-c0c534aa396b\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '216.93.243.34' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--58d7aa16-8baf-4026-b3d7-328267ed4bab\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '216.165.191.52' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--e6fd4a21-8290-40e5-9b1c-701f6f11e260\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '195.204.1.132' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--cca5ce5f-4c0e-4031-9997-063eb3badead\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '209.177.146.34' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--43a7784e-f11c-4739-91a8-dc87d05ddbb6\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '145.220.21.40' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--5716d954-e5b1-4bec-ba43-80b1053dee61\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '50.7.55.82' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--9135d4ab-a807-495b-8fff-b8433342501f\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '82.165.47.254' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--e070c86b-40e5-49ea-8d83-56bcae10b303\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '140.211.166.3' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--f4125383-930c-42ae-b57f-2c36f898d0b5\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '208.71.169.36' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--fa063c6a-1a9f-4a58-9470-ed80a23cc943\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '204.152.221.218' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--41b3ba86-dd1b-4f3d-a156-5dc27f31fb40\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '78.40.125.4' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--a9fcaba5-cd50-447d-8540-2dfe4e3c6c88\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '216.152.66.68' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--30b68eff-3c38-4c74-9783-1114a7759066\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '195.197.175.21' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--f10fa7c0-7a10-434e-908f-59a7e25e18c0\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '194.14.236.50' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--183f8cd7-2e6f-4073-bbe8-d5dc6b570fac\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '69.16.172.34' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--dd95ff3a-3ef1-409e-827b-087eb9cc3b2c\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '140.211.166.3' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--a97dc9cb-2b9f-4c1d-92cc-2fc15100e3ed\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '91.205.185.104' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--5552096e-b2b8-4057-bf5e-ccf300b8276e\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '193.163.220.3' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--0cc30ea9-eeaf-4f39-ab8d-3d2664c2b75e\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '64.202.189.170' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--7582ed02-c78d-451d-b0a5-065ae511f3ae\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '86.65.39.15' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--37fde688-ca75-4c1e-b5e1-1acb5bbfb23c\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '140.211.167.98' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--e967d3a0-0cfe-482c-b53a-390c0bb564f4\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '199.16.156.6' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--fda4f25d-8252-4593-bd8b-0a90764a561f\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '217.168.95.245' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--109b3de1-2353-42dc-8316-e2f7c0b5c67d\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '192.99.16.195' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--1efa50e4-ed2c-4fb5-ae9b-cb347bd4ad24\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '64.18.128.86' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--c7b60a1a-4c93-451f-b7c1-993c0dc14391\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '194.109.129.220' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--469381d9-c24e-4cf4-b25b-18a48975ef14\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '208.99.193.130' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--c5694bbd-3a11-4c16-ae73-eeed55acf9cc\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '70.84.101.150' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--a9b4301e-0327-4edc-b407-b7915bb0e7bc\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '64.4.30.62' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--f5ac23ca-8ab4-4597-837b-3d5e48d325cb\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '64.4.30.61' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--1a2a539b-d3f3-410b-a32c-4d1a5599364e\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '66.186.59.50' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--585e6f7b-7bad-45b0-a36b-9f3b3bff72c6\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '93.152.160.101' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--0a7dd603-d826-428f-b5f7-c82ff8bb60f3\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '216.152.66.46' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--cb2cebd2-c11f-43b1-a9a1-3c4b9893f38a\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '192.99.150.27' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--6a6c81df-7cb9-48b3-a4ea-db6924e47b5d\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '193.107.206.21' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--45177dce-6cfe-44b5-ac41-cbc1bee80527\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '69.16.172.40' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--6f58bdf5-1f26-4a17-8ba3-14c023e73a0f\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '72.51.18.254' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--d5731bef-623c-4793-994c-a6f3840bc2cf\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '193.190.67.98' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--4e8ac337-2e00-4d71-8526-bbfdb105e77f\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '140.211.166.4' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--b681b1fc-7cce-473e-81e9-f5f3657cf85b\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '130.237.188.200' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--08453fee-f3b8-449a-95a8-abc0d79710c3\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '216.155.130.130' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--79e2a4f6-ee8d-4466-8e82-ecb928e87c0d\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '208.71.169.36' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--2d3326c5-c112-4670-b6bd-6de667f4280b\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '216.152.66.47' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--4adc0666-89d1-4c67-a3c8-3b02fc351442\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '213.161.196.11' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--dc1e9fec-6d1e-46a1-902c-dc170424a23f\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '195.47.220.2' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--2d7480b1-ded5-4466-a1dd-470110eacdba\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '152.3.102.53' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--f06d6873-1538-4951-a069-d6af0dd0f8ed\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '84.208.29.17' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--4eaf258d-28d8-48d8-98f8-0d8442ba83fa\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '82.96.64.4' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--d7e4bba4-485d-4c1f-95c0-55e7d8a015f8\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '213.179.58.83' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--5c060dc8-a8cd-4067-985d-52d85ab3f256\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '128.237.157.136' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--d397fccb-3dbb-47c3-84ae-aa09f4223eca\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '193.110.95.1' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--d37d0928-c86b-474a-85ef-46e942fff510\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.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-02T20:40:44Z\",\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--5e6dd813-58bd-454e-9be7-246f3db01999\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '69.16.172.40' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--adb3c6bc-9694-471e-bf1f-0d0a02d70876\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '137.226.34.46' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--3ce88e57-edfb-45fa-81be-ed95d4564316\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '67.198.195.194' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--fbce496c-e9a6-4246-ad12-73b8f5a12a2a\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '149.9.1.16' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--efce84a3-0d17-4ae8-88be-86c86aa80bbd\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '193.109.122.77' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--20789570-8c07-42c4-8a45-b3ab170cf6ee\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '209.126.116.149' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--5c1b2889-6fec-4276-83e0-173938934ba9\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '64.250.116.136' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--bdad2fdb-71bd-49c3-8bf2-50d396fa55d5\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '163.172.17.231' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--07fd3e36-5500-4652-935f-23a2955b19f3\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '38.114.116.5' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--9e70a102-3440-4ad0-ab1d-653144632668\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '66.186.59.50' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--f566b659-ca36-42a9-8ebf-9476e6b651ab\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '195.204.1.130' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--40c0d87c-287a-4692-8227-b4976d14a5f0\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '212.27.60.27' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--da56b536-6ac7-44d5-a036-0db986926016\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '213.236.208.178' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--95f9c0f4-351b-43c9-81da-c5fdcfe4fa6d\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '94.125.182.252' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--5007db19-0906-4aec-b18b-e0819b3f13de\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '208.83.20.130' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--9e0667cd-9a83-4e19-b16f-78c3ed33bfc5\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '216.18.228.34' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--f170e9a9-abb8-4919-9902-7a5214e95cde\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '192.99.150.28' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--a30f883d-956d-4fdd-b926-db81d1893d81\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '178.79.132.147' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--8fc0e9c0-4d4d-4c4f-86a7-2f6c07cd69a4\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '193.109.122.67' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--586dc7e8-a08e-4ec2-8365-e2ee897d9ca3\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '195.47.220.2' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--16c9900c-ce48-4306-b8fa-a2de726be847\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '208.83.20.130' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--13f73e28-acf7-45b8-a5e9-6c37af914ef2\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '174.143.119.91' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--a09c4e42-8843-4c84-a75f-684bf90c5207\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '74.208.174.239' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--76646197-18a2-4513-8465-ccf72734a2e1\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '216.152.66.48' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--1169c1db-fd5b-4dcf-b4cb-9c0101ef0ea2\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '212.117.163.190' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--cdeb6ddb-5151-49ea-a488-23d806063eff\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '216.155.130.130' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--05d1ab76-d0a1-4a58-8137-98f5fdbc777c\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '90.147.160.69' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--876d7d09-248a-45ad-bcce-d92c73ad5aa3\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '89.16.176.16' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--ae1f860d-dc4f-4953-9e74-d4d7c389fdef\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '85.188.1.26' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--91bb4edc-f29f-41ba-87d9-d6a81ac8fdba\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '130.239.18.172' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--f006d048-f24f-46fa-837b-8f7fa41b43ca\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '8.7.233.233' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--436dcbec-48e2-4dc2-90f0-0876a876a38a\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '216.152.66.54' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--ff18364d-99f6-4d3d-b267-8401518af42c\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '194.68.45.50' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--8b26f167-b0ad-469b-b221-12896e2a0966\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '64.4.30.33' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--171268fb-f6a7-4085-adf5-2055a461cb93\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '64.161.254.20' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--b56c7a58-71cb-47c2-b615-f4e8a89a0732\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '141.213.238.252' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--bf09ce9a-3bb9-47c8-a686-ea1d8e1adbe8\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '213.92.8.4' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--42490e45-7350-4f48-884b-5d1610794a32\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '72.14.191.81' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--c28e91bf-a9a1-4bac-b3f3-cda89c7d28b8\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '69.16.172.2' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--ebe624b5-fb73-420a-a110-c1dc82baa6e4\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '69.61.21.115' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--ef65505f-4898-4968-82b4-f980e9705d21\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '64.18.128.86' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--b33c35ce-20f6-4fba-912c-dbf7756113f9\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '161.53.178.240' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--b3785934-f4f0-4ce7-b20c-e4384886ec45\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '204.11.244.21' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--10bbe70c-7bd3-443a-8f2c-1e56cd7a8a54\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '216.93.242.10' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--bcb54665-3461-43e2-8dbf-6b92c2413f67\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '216.152.67.23' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--a407b16b-cf5b-4f3a-a153-ba4dac5ce0e0\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '205.188.234.121' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--e7e50d3a-802d-41c8-b667-a27d29871098\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '82.96.64.4' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--017dfb8c-84b9-402f-8401-428477af7be4\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '80.88.108.18' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--84664128-cc14-480b-8d90-735727fd4b9f\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '154.35.200.44' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--f0aa750f-82cb-47f9-9c74-ace584fdadcb\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '195.68.221.222' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--9461c426-6404-4b7a-8552-c29dc60c9123\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '195.197.175.21' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--ba59cc70-03e4-47f4-871e-d40b727267f3\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '78.129.164.123' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--1b48b107-92e2-487f-9eae-3496eb64e125\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '140.211.167.99' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--e9aea5e2-9ef6-40b6-8f12-dff6ccd8eff4\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '85.25.43.27' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--cdbd95b1-17fb-4b2f-89b6-8c0f865b9e4d\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '193.219.128.49' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--afe4738d-bd3c-47de-9cc5-97e248291571\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '195.40.6.37' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--5eecb66e-f8fa-4ab9-85e4-599db7790edf\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '173.252.110.27' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--40b6b332-9a5a-42a7-8b25-6e3eb6d371d4\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '38.229.70.20' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--a16905d7-4452-4e9f-88a3-fc9338ea5116\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '38.99.64.210' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--5fcfa412-514f-43b5-b873-ed8c9b70bbb0\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '192.99.200.113' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--8259bca6-7c9c-4967-b048-a6f13f333f90\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '68.168.184.57' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\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--96763c7c-4f52-436a-919a-8b09c841f6bd\",\n", + " \"created\": \"2017-10-02T20:40:44.000Z\",\n", + " \"modified\": \"2017-10-02T20:40:44.000Z\",\n", + " \"labels\": [\n", + " \"malicious-activity\"\n", + " ],\n", + " \"name\": \"Emerging Threats - Block Rules - Compromised IPs\",\n", + " \"pattern\": \"[ ipv4-addr:value = '64.237.34.150' ]\",\n", + " \"valid_from\": \"2017-10-02T20:40:44Z\",\n", + " \"kill_chain_phases\": [\n", + " {\n", + " \"kill_chain_name\": \"lockheed-martin-cyber-kill-chain\",\n", + " \"phase_name\": \"delivery\"\n", + " }\n", + " ]\n", + "}\n" + ] + } + ], + "source": [ + "from stix2 import Filter\n", + "\n", + "# retrieve multiple object from TAXIICollectionSource\n", + "# by using filters\n", + "f1 = Filter(\"type\",\"=\", \"indicator\")\n", + "\n", + "indicators = tc_source.query([f1])\n", + "\n", + "#for visual purposes\n", + "print(\"indicators: {0}\").format(str(len(indicators)))\n", + "for indicator in indicators:\n", + " print(indicator)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "#### TAXIICollectionSink" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from stix2 import TAXIICollectionSink, ThreatActor\n", + "\n", + "#create TAXIICollectionSINK and push STIX content to it\n", + "tc_sink = TAXIICollectionSink(collection)\n", + "\n", + "# create new STIX threat-actor\n", + "ta = ThreatActor(name=\"Teddy Bear\",\n", + " labels=[\"nation-state\"],\n", + " sophistication=\"innovator\",\n", + " resource_level=\"government\",\n", + " goals=[\n", + " \"compromising environment NGOs\",\n", + " \"water-hole attacks geared towards energy sector\",\n", + " ])\n", + "\n", + "tc_sink.add(ta)\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### TAXIICollectionStore" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " \"type\": \"indicator\",\n", + " \"id\": \"indicator--d8e1cd37-4a6c-4088-aded-ed79c4ea2caa\",\n", + " \"created\": \"2017-10-02T20:24:03.000Z\",\n", + " \"modified\": \"2017-10-02T20:24:03.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-02T20:24:03Z\",\n", + " \"kill_chain_phases\": [\n", + " {\n", + " \"kill_chain_name\": \"lockheed-martin-cyber-kill-chain\",\n", + " \"phase_name\": \"delivery\"\n", + " }\n", + " ]\n", + "}\n" + ] + } + ], + "source": [ + "from stix2 import TAXIICollectionStore\n", + "\n", + "# create TAXIICollectionStore - note the same collection instance can\n", + "# be used for the store\n", + "tc_store = TAXIICollectionStore(collection)\n", + "\n", + "# retrieve STIX object by id from TAXII Collection through\n", + "# TAXIICollectionStore\n", + "stix_obj2 = tc_source.get(\"indicator--6850d393-36b6-4a67-ad45-f9e4d512c799\")\n", + "\n", + "print(stix_obj2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from stix2 import indicator\n", + "\n", + "# add STIX object to TAXIICollectionStore\n", + "ind = Indicator(description=\"Smokey Bear implant\",\n", + " labels=[\"malicious-activity\"],\n", + " pattern=\"[file:hashes.'SHA-256' = '09c7e05a39a59428743635242e4a867c932140a909f12a1e54fa7ee6a440c73b']\")\n", + "\n", + "tc_store.add(ind)\n" + ] + } + ], + "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 +} diff --git a/docs/guide/versioning.ipynb b/docs/guide/versioning.ipynb new file mode 100644 index 0000000..30ceb69 --- /dev/null +++ b/docs/guide/versioning.ipynb @@ -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('{}'.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": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "id": "indicator--92bb1ae4-db9c-4d6e-8ded-ef7280b4439a",\n",
+       "    "created": "2016-01-01T08:00:00.000Z",\n",
+       "    "modified": "2017-09-26T23:39:07.149Z",\n",
+       "    "labels": [\n",
+       "        "malicious-activity"\n",
+       "    ],\n",
+       "    "name": "File hash for Foobar malware",\n",
+       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+       "    "valid_from": "2017-09-26T23:39:07.132129Z"\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "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 can’t 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": [ + "
{\n",
+       "    "type": "indicator",\n",
+       "    "id": "indicator--92bb1ae4-db9c-4d6e-8ded-ef7280b4439a",\n",
+       "    "created": "2016-01-01T08:00:00.000Z",\n",
+       "    "modified": "2017-09-26T23:39:09.463Z",\n",
+       "    "labels": [\n",
+       "        "malicious-activity"\n",
+       "    ],\n",
+       "    "name": "File hash for Foobar malware",\n",
+       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+       "    "valid_from": "2017-09-26T23:39:07.132129Z",\n",
+       "    "revoked": true\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "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 +} diff --git a/docs/index.rst b/docs/index.rst index 7e8723d..62d07ff 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -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 diff --git a/docs/overview.rst b/docs/overview.rst index 643253c..9802843 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -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 diff --git a/requirements.txt b/requirements.txt index 605bc54..93328de 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ bumpversion +nbsphinx pre-commit pytest pytest-cov diff --git a/stix2/__init__.py b/stix2/__init__.py index 53c2fb1..55911a4 100644 --- a/stix2/__init__.py +++ b/stix2/__init__.py @@ -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, diff --git a/stix2/base.py b/stix2/base.py index 5608102..5307393 100644 --- a/stix2/base.py +++ b/stix2/base.py @@ -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 diff --git a/stix2/common.py b/stix2/common.py index d7994c6..449cd54 100644 --- a/stix2/common.py +++ b/stix2/common.py @@ -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) @@ -66,7 +66,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. """ @@ -77,7 +77,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() _properties.update([ @@ -121,17 +121,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): diff --git a/stix2/core.py b/stix2/core.py index 0271e34..3eaabb0 100644 --- a/stix2/core.py +++ b/stix2/core.py @@ -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 diff --git a/stix2/exceptions.py b/stix2/exceptions.py index 32db472..841a8e9 100644 --- a/stix2/exceptions.py +++ b/stix2/exceptions.py @@ -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) diff --git a/stix2/markings/__init__.py b/stix2/markings/__init__.py index 41c761d..4038a5e 100644 --- a/stix2/markings/__init__.py +++ b/stix2/markings/__init__.py @@ -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 diff --git a/stix2/markings/granular_markings.py b/stix2/markings/granular_markings.py index 5afd1cc..3fe3a48 100644 --- a/stix2/markings/granular_markings.py +++ b/stix2/markings/granular_markings.py @@ -1,3 +1,5 @@ +"""Functions for working with STIX 2.0 granular markings. +""" from stix2 import exceptions from stix2.markings import utils diff --git a/stix2/markings/object_markings.py b/stix2/markings/object_markings.py index a775ddc..cb78294 100644 --- a/stix2/markings/object_markings.py +++ b/stix2/markings/object_markings.py @@ -1,3 +1,5 @@ +"""Functions for working with STIX 2.0 object markings. +""" from stix2 import exceptions from stix2.markings import utils diff --git a/stix2/markings/utils.py b/stix2/markings/utils.py index 1154d19..3024fe8 100644 --- a/stix2/markings/utils.py +++ b/stix2/markings/utils.py @@ -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. diff --git a/stix2/observables.py b/stix2/observables.py index 137b388..57add29 100644 --- a/stix2/observables.py +++ b/stix2/observables.py @@ -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): @@ -923,7 +931,14 @@ def CustomExtension(observable=None, type='x-custom-observable', properties=None 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 diff --git a/stix2/patterns.py b/stix2/patterns.py index 03b7657..94ae7d2 100644 --- a/stix2/patterns.py +++ b/stix2/patterns.py @@ -1,3 +1,6 @@ +"""Classes to aid in working with the STIX 2 patterning language. +""" + import base64 import binascii import re diff --git a/stix2/properties.py b/stix2/properties.py index 4889a45..afe994f 100644 --- a/stix2/properties.py +++ b/stix2/properties.py @@ -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 diff --git a/stix2/sdo.py b/stix2/sdo.py index 4664d99..8dad686 100644 --- a/stix2/sdo.py +++ b/stix2/sdo.py @@ -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, IDProperty, IntegerProperty, ListProperty, PatternProperty, ReferenceProperty, @@ -14,7 +14,7 @@ from .properties import (BooleanProperty, IDProperty, IntegerProperty, from .utils import NOW -class STIXDomainObject(_STIXBase, MarkingsMixin): +class STIXDomainObject(_STIXBase, _MarkingsMixin): pass @@ -293,30 +293,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): @@ -351,7 +349,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 diff --git a/stix2/sources/__init__.py b/stix2/sources/__init__.py index 6fcd17b..9d46ba9 100644 --- a/stix2/sources/__init__.py +++ b/stix2/sources/__init__.py @@ -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: diff --git a/stix2/sources/filesystem.py b/stix2/sources/filesystem.py index 4a407b6..103b882 100644 --- a/stix2/sources/filesystem.py +++ b/stix2/sources/filesystem.py @@ -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)] diff --git a/stix2/sources/filters.py b/stix2/sources/filters.py index 3b476a3..060d2c3 100644 --- a/stix2/sources/filters.py +++ b/stix2/sources/filters.py @@ -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: diff --git a/stix2/sources/memory.py b/stix2/sources/memory.py index 91363ea..0d5901e 100644 --- a/stix2/sources/memory.py +++ b/stix2/sources/memory.py @@ -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. diff --git a/stix2/sources/taxii.py b/stix2/sources/taxii.py index aeb38c8..7ecedca 100644 --- a/stix2/sources/taxii.py +++ b/stix2/sources/taxii.py @@ -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: diff --git a/stix2/sro.py b/stix2/sro.py index 4fa0465..60f99f5 100644 --- a/stix2/sro.py +++ b/stix2/sro.py @@ -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 diff --git a/stix2/test/test_custom.py b/stix2/test/test_custom.py index 77598ca..ff432c1 100644 --- a/stix2/test/test_custom.py +++ b/stix2/test/test_custom.py @@ -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', [ @@ -380,6 +420,26 @@ def test_custom_extension_empty_properties(): 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", diff --git a/stix2/test/test_indicator.py b/stix2/test/test_indicator.py index d2c046f..c501da4 100644 --- a/stix2/test/test_indicator.py +++ b/stix2/test/test_indicator.py @@ -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 diff --git a/stix2/utils.py b/stix2/utils.py index 94e7f4e..8df4323 100644 --- a/stix2/utils.py +++ b/stix2/utils.py @@ -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.')