{ "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", " 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\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--2f3d4926-163d-4aef-bcd2-19dea96916ae",\n",
       "    "created": "2019-05-13T13:14:48.509Z",\n",
       "    "modified": "2019-05-13T13:14:48.509Z",\n",
       "    "name": "File hash for malware variant",\n",
       "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
       "    "valid_from": "2019-05-13T13:14:48.509629Z",\n",
       "    "labels": [\n",
       "        "malicious-activity"\n",
       "    ]\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": {}, "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": [ "'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": [ "'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](versioning.ipynb) 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--1f2aba70-f0ae-49cd-9267-6fcb1e43be67",\n",
       "    "created": "2019-05-13T13:15:04.698Z",\n",
       "    "modified": "2019-05-13T13:15:04.698Z",\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.\n", "\n", "You can see the full list of SDO classes [here](../api/v20/stix2.v20.sdo.rst)." ] }, { "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--80c174fa-36d1-47c2-9a9d-ce0c636bedcc",\n",
       "    "created": "2019-05-13T13:15:13.152Z",\n",
       "    "modified": "2019-05-13T13:15:13.152Z",\n",
       "    "relationship_type": "indicates",\n",
       "    "source_ref": "indicator--2f3d4926-163d-4aef-bcd2-19dea96916ae",\n",
       "    "target_ref": "malware--1f2aba70-f0ae-49cd-9267-6fcb1e43be67"\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--47395d23-dedd-45d4-8db1-c9ffaf44493d",\n",
       "    "created": "2019-05-13T13:15:16.566Z",\n",
       "    "modified": "2019-05-13T13:15:16.566Z",\n",
       "    "relationship_type": "indicates",\n",
       "    "source_ref": "indicator--2f3d4926-163d-4aef-bcd2-19dea96916ae",\n",
       "    "target_ref": "malware--1f2aba70-f0ae-49cd-9267-6fcb1e43be67"\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--388c9b2c-936c-420a-baa5-04f48d682a01",\n",
       "    "spec_version": "2.0",\n",
       "    "objects": [\n",
       "        {\n",
       "            "type": "indicator",\n",
       "            "id": "indicator--2f3d4926-163d-4aef-bcd2-19dea96916ae",\n",
       "            "created": "2019-05-13T13:14:48.509Z",\n",
       "            "modified": "2019-05-13T13:14:48.509Z",\n",
       "            "name": "File hash for malware variant",\n",
       "            "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
       "            "valid_from": "2019-05-13T13:14:48.509629Z",\n",
       "            "labels": [\n",
       "                "malicious-activity"\n",
       "            ]\n",
       "        },\n",
       "        {\n",
       "            "type": "malware",\n",
       "            "id": "malware--1f2aba70-f0ae-49cd-9267-6fcb1e43be67",\n",
       "            "created": "2019-05-13T13:15:04.698Z",\n",
       "            "modified": "2019-05-13T13:15:04.698Z",\n",
       "            "name": "Poison Ivy",\n",
       "            "labels": [\n",
       "                "remote-access-trojan"\n",
       "            ]\n",
       "        },\n",
       "        {\n",
       "            "type": "relationship",\n",
       "            "id": "relationship--80c174fa-36d1-47c2-9a9d-ce0c636bedcc",\n",
       "            "created": "2019-05-13T13:15:13.152Z",\n",
       "            "modified": "2019-05-13T13:15:13.152Z",\n",
       "            "relationship_type": "indicates",\n",
       "            "source_ref": "indicator--2f3d4926-163d-4aef-bcd2-19dea96916ae",\n",
       "            "target_ref": "malware--1f2aba70-f0ae-49cd-9267-6fcb1e43be67"\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)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Creating Cyber Observable References\n", "Cyber Observable Objects have properties that can reference other Cyber Observable Objects. In order to create those references, use the ``_valid_refs`` property as shown in the following examples. It should be noted that ``_valid_refs`` is necessary when creating references to Cyber Observable Objects since some embedded references can only point to certain types, and ``_valid_refs`` helps ensure consistency. \n", "\n", "There are two cases." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Case 1: Specifying the type of the Cyber Observable Objects being referenced\n", "In the following example, the IPv4Address object has its ``resolves_to_refs`` property specified. As per the spec, this property's value must be a list of reference(s) to MACAddress objects. In this case, those references are strings that state the type of the Cyber Observable Object being referenced, and are provided in ``_valid_refs``." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
{\n",
       "    "type": "ipv4-addr",\n",
       "    "value": "177.60.40.7",\n",
       "    "resolves_to_refs": [\n",
       "        "1",\n",
       "        "2"\n",
       "    ]\n",
       "}\n",
       "
\n" ], "text/plain": [ "" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from stix2 import IPv4Address\n", "\n", "ip4 = IPv4Address(\n", " _valid_refs={\"1\": \"mac-addr\", \"2\": \"mac-addr\"},\n", " value=\"177.60.40.7\",\n", " resolves_to_refs=[\"1\", \"2\"]\n", ")\n", "\n", "print(ip4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Case 2: Specifying the name of the Cyber Observable Objects being referenced\n", "The following example is just like the one provided in Case 1 above, with one key difference: instead of using strings to specify the type of the Cyber Observable Objects being referenced in ``_valid_refs``, the referenced Cyber Observable Objects are created beforehand and then their names are provided in ``_valid_refs``." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
{\n",
       "    "type": "ipv4-addr",\n",
       "    "value": "177.60.40.7",\n",
       "    "resolves_to_refs": [\n",
       "        "1",\n",
       "        "2"\n",
       "    ]\n",
       "}\n",
       "
\n" ], "text/plain": [ "" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from stix2 import MACAddress\n", "\n", "mac_addr_a = MACAddress(value=\"a1:b2:c3:d4:e5:f6\")\n", "mac_addr_b = MACAddress(value=\"a7:b8:c9:d0:e1:f2\")\n", "\n", "ip4_valid_refs = IPv4Address(\n", " _valid_refs={\"1\": mac_addr_a, \"2\": mac_addr_b},\n", " value=\"177.60.40.7\",\n", " resolves_to_refs=[\"1\", \"2\"]\n", ")\n", "\n", "print(ip4_valid_refs)" ] } ], "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.6.7" } }, "nbformat": 4, "nbformat_minor": 2 }