Using The Workbench

The Workbench API hides most of the complexity of the rest of the library to make it easy to interact with STIX data. To use it, just import everything from stix2.workbench:

[3]:
from stix2.workbench import *

Retrieving STIX Data

To get some STIX data to work with, let’s set up a DataSource and add it to our workbench.

[4]:
from taxii2client import Collection

collection = Collection("http://127.0.0.1:5000/trustgroup1/collections/91a7b528-80eb-42ed-a74d-c6fbd5a26116/", user="admin", password="Password0")
tc_source = TAXIICollectionSource(collection)
add_data_source(tc_source)

Now we can get all of the indicators from the data source.

[5]:
response = indicators()

Similar functions are available for the other STIX Object types. See the full list here.

If you want to only retrieve some indicators, you can pass in one or more Filters. This example finds all the indicators created by a specific identity:

[6]:
response = indicators(filters=Filter('created_by_ref', '=', 'identity--adede3e8-bf44-4e6f-b3c9-1958cbc3b188'))

The objects returned let you easily traverse their relationships. Get all Relationship objects involving that object with .relationships(), all other objects related to this object with .related(), and the Identity object for the creator of the object (if one exists) with .created_by(). For full details on these methods and their arguments, see the Workbench API documentation.

[7]:
for i in indicators():
    for rel in i.relationships():
        print(rel.source_ref)
        print(rel.relationship_type)
        print(rel.target_ref)
[7]:
indicator--cd981c25-8042-4166-8945-51178443bdac
[7]:
indicates
[7]:
malware--c0931cc6-c75e-47e5-9036-78fabc95d4ec
[8]:
for i in indicators():
    for obj in i.related():
        print(obj.serialize(pretty=True))
[8]:
{
    "type": "malware",
    "spec_version": "2.1",
    "id": "malware--c0931cc6-c75e-47e5-9036-78fabc95d4ec",
    "created": "2017-01-27T13:49:53.997Z",
    "modified": "2017-01-27T13:49:53.997Z",
    "name": "Poison Ivy",
    "description": "Poison Ivy",
    "malware_types": [
        "remote-access-trojan"
    ],
    "is_family": true
}

If there are a lot of related objects, you can narrow it down by passing in one or more Filters just as before. For example, if we want to get only the indicators related to a specific piece of malware (and not any entities that use it or are targeted by it):

[10]:
malware = get('malware--c0931cc6-c75e-47e5-9036-78fabc95d4ec')
indicator = malware.related(filters=Filter('type', '=', 'indicator'))
print(indicator[0].serialize(pretty=True))
[10]:
{
    "type": "indicator",
    "spec_version": "2.1",
    "id": "indicator--cd981c25-8042-4166-8945-51178443bdac",
    "created": "2014-05-08T09:00:00.000Z",
    "modified": "2014-05-08T09:00:00.000Z",
    "name": "File hash for Poison Ivy variant",
    "indicator_types": [
        "file-hash-watchlist"
    ],
    "pattern": "[file:hashes.'SHA-256' = 'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c']",
    "pattern_type": "stix",
    "pattern_version": "2.1",
    "valid_from": "2014-05-08T09:00:00Z"
}

Creating STIX Data

To create a STIX object, just use that object’s class constructor. Once it’s created, add it to the workbench with save().

[11]:
identity = Identity(name="ACME Threat Intel Co.", identity_class="organization")
save(identity)

You can also set defaults for certain properties when creating objects. For example, let’s set the default creator to be the identity object we just created:

[12]:
set_default_creator(identity)

Now when we create an indicator (or any other STIX Domain Object), it will automatically have the right create_by_ref value.

[14]:
indicator = Indicator(pattern_type="stix", pattern="[file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e']")
save(indicator)

indicator_creator = get(indicator.created_by_ref)
print(indicator_creator.name)
[14]:
ACME Threat Intel Co.

Defaults can also be set for the created timestamp, external references and object marking references.

Warning

The workbench layer replaces STIX Object classes with special versions of them that use “wrappers” to provide extra functionality. Because of this, we recommend that you either use the workbench layer or the rest of the library, but not both. In other words, don’t import from both stix2.workbench and any other submodules of stix2.