{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "nbsphinx": "hidden" }, "outputs": [], "source": [ "# Delete this cell to re-enable tracebacks\n", "import sys\n", "ipython = get_ipython()\n", "\n", "def hide_traceback(exc_tuple=None, filename=None, tb_offset=None,\n", " exception_only=False, running_compiled_code=False):\n", " etype, value, tb = sys.exc_info()\n", " value.__cause__ = None # suppress chained exceptions\n", " return ipython._showtraceback(etype, value, ipython.InteractiveTB.get_exception_only(etype, value))\n", "\n", "ipython.showtraceback = hide_traceback" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "nbsphinx": "hidden" }, "outputs": [], "source": [ "# JSON output syntax highlighting\n", "from __future__ import print_function\n", "from pygments import highlight\n", "from pygments.lexers import JsonLexer, TextLexer\n", "from pygments.formatters import HtmlFormatter\n", "from IPython.display import display, HTML\n", "from IPython.core.interactiveshell import InteractiveShell\n", "\n", "InteractiveShell.ast_node_interactivity = \"all\"\n", "\n", "def json_print(inpt):\n", " string = str(inpt)\n", " formatter = HtmlFormatter()\n", " if string[0] == '{':\n", " lexer = JsonLexer()\n", " else:\n", " lexer = TextLexer()\n", " return HTML('{}'.format(\n", " formatter.get_style_defs('.highlight'),\n", " highlight(string, lexer, formatter)))\n", "\n", "globals()['print'] = json_print" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## STIX Extensions\n", "\n", "This page is specific for the STIX Extensions mechanism defined in STIX 2.1 CS 02. For the deprecated STIX Customization mechanisms see the [Custom](custom.ipynb) section.\n", "\n", "### Top Level Property Extensions\n", "\n", "The example below shows how to create an `indicator` object with a `top-level-property-extension`. " ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
{\n",
       "    "type": "extension-definition",\n",
       "    "spec_version": "2.1",\n",
       "    "id": "extension-definition--dd73de4f-a7f3-49ea-8ec1-8e884196b7a8",\n",
       "    "created_by_ref": "identity--11b76a96-5d2b-45e0-8a5a-f6994f370731",\n",
       "    "created": "2014-02-20T09:16:08.000Z",\n",
       "    "modified": "2014-02-20T09:16:08.000Z",\n",
       "    "name": "New SDO 1",\n",
       "    "description": "This schema adds two properties to a STIX object at the toplevel",\n",
       "    "schema": "https://www.example.com/schema-foo-1a/v1/",\n",
       "    "version": "1.2.1",\n",
       "    "extension_types": [\n",
       "        "toplevel-property-extension"\n",
       "    ],\n",
       "    "extension_properties": [\n",
       "        "toxicity",\n",
       "        "rank"\n",
       "    ]\n",
       "}\n",
       "
\n" ], "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/html": [ "
{\n",
       "    "type": "indicator",\n",
       "    "spec_version": "2.1",\n",
       "    "id": "indicator--e97bfccf-8970-4a3c-9cd1-5b5b97ed5d0c",\n",
       "    "created": "2014-02-20T09:16:08.989Z",\n",
       "    "modified": "2014-02-20T09:16:08.989Z",\n",
       "    "name": "File hash for Poison Ivy variant",\n",
       "    "description": "This file hash indicates that a sample of Poison Ivy is present.",\n",
       "    "pattern": "[file:hashes.'SHA-256' = 'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c']",\n",
       "    "pattern_type": "stix",\n",
       "    "pattern_version": "2.1",\n",
       "    "valid_from": "2014-02-20T09:00:00Z",\n",
       "    "labels": [\n",
       "        "malicious-activity"\n",
       "    ],\n",
       "    "extensions": {\n",
       "        "extension-definition--dd73de4f-a7f3-49ea-8ec1-8e884196b7a8": {\n",
       "            "extension_type": "toplevel-property-extension"\n",
       "        }\n",
       "    },\n",
       "    "rank": 5,\n",
       "    "toxicity": 8\n",
       "}\n",
       "
\n" ], "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import stix2\n", "\n", "extension_definition1 = stix2.v21.ExtensionDefinition(\n", " id=\"extension-definition--dd73de4f-a7f3-49ea-8ec1-8e884196b7a8\",\n", " created_by_ref=\"identity--11b76a96-5d2b-45e0-8a5a-f6994f370731\",\n", " created=\"2014-02-20T09:16:08.000Z\",\n", " modified=\"2014-02-20T09:16:08.000Z\",\n", " name=\"New SDO 1\",\n", " description=\"This schema adds two properties to a STIX object at the toplevel\",\n", " schema=\"https://www.example.com/schema-foo-1a/v1/\",\n", " version=\"1.2.1\",\n", " extension_types=[\"toplevel-property-extension\"],\n", " extension_properties=[\n", " \"toxicity\",\n", " \"rank\",\n", " ],\n", ")\n", "\n", "indicator = stix2.v21.Indicator(\n", " id='indicator--e97bfccf-8970-4a3c-9cd1-5b5b97ed5d0c',\n", " created='2014-02-20T09:16:08.989000Z',\n", " modified='2014-02-20T09:16:08.989000Z',\n", " name='File hash for Poison Ivy variant',\n", " description='This file hash indicates that a sample of Poison Ivy is present.',\n", " labels=[\n", " 'malicious-activity',\n", " ],\n", " rank=5,\n", " toxicity=8,\n", " pattern='[file:hashes.\\'SHA-256\\' = \\'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c\\']',\n", " pattern_type='stix',\n", " valid_from='2014-02-20T09:00:00.000000Z',\n", " extensions={\n", " extension_definition1.id : {\n", " 'extension_type': 'toplevel-property-extension',\n", " },\n", " }\n", ")\n", "\n", "print(extension_definition1.serialize(pretty=True))\n", "print(indicator.serialize(pretty=True))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using CustomExtension decorator\n", "\n", "However, in order to prevent repetitive instantiation of the same extension, the `@CustomExtension` decorator can be used to register the `extension-definition` with stix2. Use the `extension_type` class variable to define what kind of extension it is. Then its id can be passed into objects that use this extension." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
{\n",
       "    "type": "indicator",\n",
       "    "spec_version": "2.1",\n",
       "    "id": "indicator--e97bfccf-8970-4a3c-9cd1-5b5b97ed5d0c",\n",
       "    "created": "2014-02-20T09:16:08.989Z",\n",
       "    "modified": "2014-02-20T09:16:08.989Z",\n",
       "    "name": "File hash for Poison Ivy variant",\n",
       "    "description": "This file hash indicates that a sample of Poison Ivy is present.",\n",
       "    "pattern": "[file:hashes.'SHA-256' = 'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c']",\n",
       "    "pattern_type": "stix",\n",
       "    "pattern_version": "2.1",\n",
       "    "valid_from": "2014-02-20T09:00:00Z",\n",
       "    "labels": [\n",
       "        "malicious-activity"\n",
       "    ],\n",
       "    "extensions": {\n",
       "        "extension-definition--dd73de4f-a7f3-49ea-8ec1-8e884196b7a8": {\n",
       "            "extension_type": "toplevel-property-extension"\n",
       "        }\n",
       "    },\n",
       "    "rank": 5,\n",
       "    "toxicity": 8\n",
       "}\n",
       "
\n" ], "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "TOPLEVEL_EXTENSION_DEFINITION_ID = 'extension-definition--dd73de4f-a7f3-49ea-8ec1-8e884196b7a8'\n", "\n", "@stix2.v21.CustomExtension(\n", " TOPLEVEL_EXTENSION_DEFINITION_ID, [\n", " ('rank', stix2.properties.IntegerProperty(required=True)),\n", " ('toxicity', stix2.properties.IntegerProperty(required=True)),\n", " ],\n", ")\n", "class ExtensionTopLevel:\n", " extension_type = 'toplevel-property-extension'\n", "\n", "indicator = stix2.v21.Indicator(\n", " id='indicator--e97bfccf-8970-4a3c-9cd1-5b5b97ed5d0c',\n", " created='2014-02-20T09:16:08.989000Z',\n", " modified='2014-02-20T09:16:08.989000Z',\n", " name='File hash for Poison Ivy variant',\n", " description='This file hash indicates that a sample of Poison Ivy is present.',\n", " labels=[\n", " 'malicious-activity',\n", " ],\n", " rank=5,\n", " toxicity=8,\n", " pattern='[file:hashes.\\'SHA-256\\' = \\'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c\\']',\n", " pattern_type='stix',\n", " valid_from='2014-02-20T09:00:00.000000Z',\n", " extensions={\n", " TOPLEVEL_EXTENSION_DEFINITION_ID : {\n", " 'extension_type': 'toplevel-property-extension',\n", " },\n", " }\n", ")\n", "\n", "print(indicator.serialize(pretty=True))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using CustomObservable for Extension Definition\n", "\n", "Similarly, when registering new objects via `@CustomObservable` you can pass the `extension-definition` id that defines this new SCO. \n", "\n", "---\n", "**Note:**\n", "Creating an instance of an extension-definition object **does not** mean it is registered in the library. Please use the appropriate decorator for this step: `@CustomExtension`, `@CustomObject`, `@CustomObservable`, `@CustomMarking`\n", "\n", "---" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
{\n",
       "    "type": "my-favorite-sco",\n",
       "    "spec_version": "2.1",\n",
       "    "id": "my-favorite-sco--f9dbe89c-0030-4a9d-8b78-0dcd0a0de874",\n",
       "    "name": "This is the name of my favorite SCO",\n",
       "    "some_network_protocol_field": "value",\n",
       "    "extensions": {\n",
       "        "extension-definition--150c1738-28c9-44d0-802d-70523218240b": {\n",
       "            "extension_type": "new-sco"\n",
       "        }\n",
       "    }\n",
       "}\n",
       "
\n" ], "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@stix2.v21.CustomObservable(\n", " 'my-favorite-sco', [\n", " ('name', stix2.properties.StringProperty(required=True)),\n", " ('some_network_protocol_field', stix2.properties.StringProperty(required=True)),\n", " ], ['name', 'some_network_protocol_field'], 'extension-definition--150c1738-28c9-44d0-802d-70523218240b',\n", ")\n", "class MyFavSCO:\n", " pass\n", "\n", "my_favorite_sco = MyFavSCO(\n", " id='my-favorite-sco--f9dbe89c-0030-4a9d-8b78-0dcd0a0de874',\n", " name='This is the name of my favorite SCO',\n", " some_network_protocol_field='value',\n", ")\n", "\n", "print(my_favorite_sco.serialize(pretty=True))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using CustomMarking for Extension Definition\n", "\n", "The example below shows the use for MarkingDefinition extensions. Currently this is only supported as a `property-extension`. Now, as another option to building the `extensions` as a dictionary, it can also be built with objects as shown below by extracting the registered class." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
{\n",
       "    "type": "marking-definition",\n",
       "    "spec_version": "2.1",\n",
       "    "id": "marking-definition--28417f9f-1963-4e7f-914d-233f8fd4829f",\n",
       "    "created": "2021-03-31T21:54:46.652069Z",\n",
       "    "name": "This is the name of my favorite Marking",\n",
       "    "extensions": {\n",
       "        "extension-definition--a932fcc6-e032-176c-126f-cb970a5a1fff": {\n",
       "            "extension_type": "property-extension"\n",
       "        }\n",
       "    }\n",
       "}\n",
       "
\n" ], "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from stix2 import registry\n", "\n", "MARKING_EXTENSION_ID = 'extension-definition--a932fcc6-e032-176c-126f-cb970a5a1fff'\n", "\n", "@stix2.v21.CustomMarking(\n", " 'my-favorite-marking', [\n", " ('some_marking_field', stix2.properties.StringProperty(required=True)),\n", " ], MARKING_EXTENSION_ID,\n", ")\n", "class MyFavMarking:\n", " pass\n", "\n", "ext_class = registry.class_for_type(MARKING_EXTENSION_ID, '2.1')\n", "\n", "my_favorite_marking = MyFavMarking(\n", " name='This is the name of my favorite Marking',\n", " extensions={\n", " MARKING_EXTENSION_ID: ext_class(some_marking_field='value')\n", " }\n", ")\n", "\n", "print(my_favorite_marking.serialize(pretty=True))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using CustomObject for Extension Definition\n", "\n", "Similar to the examples above, the same can be done for SDOs and SROs." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
{\n",
       "    "type": "my-favorite-sro",\n",
       "    "spec_version": "2.1",\n",
       "    "id": "my-favorite-sro--d6306d62-c08d-4d78-baf7-11e7a4c9bc36",\n",
       "    "created": "2021-03-31T22:43:42.807698Z",\n",
       "    "modified": "2021-03-31T22:43:42.807698Z",\n",
       "    "name": "My First SRO",\n",
       "    "some_source_ref": "identity--b1da8c3e-34d8-470f-9d2b-392e275f1f7d",\n",
       "    "some_target_ref": "identity--1ddfed54-e8cd-49c9-9c7d-8d1b03c94685",\n",
       "    "extensions": {\n",
       "        "extension-definition--e96690a5-dc13-4f27-99dd-0f2188ad74ce": {\n",
       "            "extension_type": "new-sro"\n",
       "        }\n",
       "    }\n",
       "}\n",
       "
\n" ], "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "invalid_refs = ['bundle', 'language-content', 'marking-definition', 'relationship', 'sighting', 'foobar']\n", "\n", "@stix2.v21.CustomObject(\n", " 'my-favorite-sro', [\n", " ('name', stix2.properties.StringProperty(required=False)),\n", " ('some_source_ref', stix2.properties.ReferenceProperty(invalid_types=invalid_refs, spec_version='2.1', required=True)),\n", " ('some_target_ref', stix2.properties.ReferenceProperty(invalid_types=invalid_refs, spec_version='2.1', required=True)),\n", " ], extension_name='extension-definition--e96690a5-dc13-4f27-99dd-0f2188ad74ce', is_sdo=False,\n", ")\n", "class MyFavSRO:\n", " pass\n", "\n", "\n", "my_favorite_sro = MyFavSRO(\n", " name=\"My First SRO\",\n", " some_source_ref=\"identity--b1da8c3e-34d8-470f-9d2b-392e275f1f7d\",\n", " some_target_ref=\"identity--1ddfed54-e8cd-49c9-9c7d-8d1b03c94685\",\n", ")\n", "\n", "print(my_favorite_sro.serialize(pretty=True))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.2" } }, "nbformat": 4, "nbformat_minor": 2 }