Parsing STIX Content

Parsing STIX content is as easy as calling the parse() function on a JSON string, dictionary, or file-like object. 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.

Parsing a string

In [3]:
from stix2 import parse

input_string = """{
    "type": "observed-data",
    "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf",
    "created": "2016-04-06T19:58:16.000Z",
    "modified": "2016-04-06T19:58:16.000Z",
    "first_observed": "2015-12-21T19:00:00Z",
    "last_observed": "2015-12-21T19:00:00Z",
    "number_observed": 50,
    "objects": {
        "0": {
            "type": "file",
            "hashes": {
                "SHA-256": "0969de02ecf8a5f003e3f6d063d848c8a193aada092623f8ce408c15bcb5f038"
            }
        }
    }
}"""

obj = parse(input_string)
print(type(obj))
print(obj)
Out[3]:
<class 'stix2.v20.sdo.ObservedData'>
Out[3]:
{
    "type": "observed-data",
    "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf",
    "created": "2016-04-06T19:58:16.000Z",
    "modified": "2016-04-06T19:58:16.000Z",
    "first_observed": "2015-12-21T19:00:00Z",
    "last_observed": "2015-12-21T19:00:00Z",
    "number_observed": 50,
    "objects": {
        "0": {
            "type": "file",
            "hashes": {
                "SHA-256": "0969de02ecf8a5f003e3f6d063d848c8a193aada092623f8ce408c15bcb5f038"
            }
        }
    }
}

Parsing a dictionary

In [4]:
input_dict = {
    "type": "identity",
    "id": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c",
    "created": "2015-12-21T19:59:11Z",
    "modified": "2015-12-21T19:59:11Z",
    "name": "Cole Powers",
    "identity_class": "individual"
}

obj = parse(input_dict)
print(type(obj))
print(obj)
Out[4]:
<class 'stix2.v20.sdo.Identity'>
Out[4]:
{
    "type": "identity",
    "id": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c",
    "created": "2015-12-21T19:59:11.000Z",
    "modified": "2015-12-21T19:59:11.000Z",
    "name": "Cole Powers",
    "identity_class": "individual"
}

Parsing a file-like object

In [5]:
file_handle = open("/tmp/stix2_store/course-of-action/course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd.json")

obj = parse(file_handle)
print(type(obj))
print(obj)
Out[5]:
<class 'stix2.v20.sdo.CourseOfAction'>
Out[5]:
{
    "type": "course-of-action",
    "id": "course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd",
    "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5",
    "created": "2017-05-31T21:30:41.022Z",
    "modified": "2017-05-31T21:30:41.022Z",
    "name": "Data from Network Shared Drive Mitigation",
    "description": "Identify unnecessary system utilities or potentially malicious software that may be used to collect data from a network share, and audit and/or block them by using whitelisting[[CiteRef::Beechey 2010]] tools, like AppLocker,[[CiteRef::Windows Commands JPCERT]][[CiteRef::NSA MS AppLocker]] or Software Restriction Policies[[CiteRef::Corio 2008]] where appropriate.[[CiteRef::TechNet Applocker vs SRP]]"
}

Parsing Custom STIX Content

Parsing custom STIX objects and/or STIX objects with custom properties is also completed easily with parse(). Just supply the keyword argument allow_custom=True. When allow_custom is specified, parse() will attempt to convert the supplied STIX content to known STIX 2 domain objects and/or previously defined custom STIX 2 objects. If the conversion cannot be completed (and allow_custom is specified), parse() will treat the supplied STIX 2 content as valid STIX 2 objects and return them. Warning: Specifying allow_custom may lead to critical errors if further processing (searching, filtering, modifying etc...) of the custom content occurs where the custom content supplied is not valid STIX 2. This is an axiomatic possibility as the stix2 library cannot guarantee proper processing of unknown custom STIX 2 objects that were explicitly flagged to be allowed, and thus may not be valid.

For examples of parsing STIX 2 objects with custom STIX properties, see Custom STIX Content: Custom Properties

For examples of parsing defined custom STIX 2 objects, see Custom STIX Content: Custom STIX Object Types

For retrieving STIX 2 content from a source (e.g. file system, TAXII) that may possibly have custom STIX 2 content unknown to the user, the user can create a STIX 2 DataStore/Source with the flag allow_custom=True. As mentioned, this will configure the DataStore/Source to allow for unknown STIX 2 content to be returned (albeit not converted to full STIX 2 domain objects and properties); the stix2 library may preclude processing the unknown content, if the content is not valid or actual STIX 2 domain objects and properties.

In [ ]:
from taxii2client import Collection
from stix2 import CompositeDataSource, FileSystemSource, TAXIICollectionSource

# to allow for the retrieval of unknown custom STIX2 content,
# just create *Stores/*Sources with the 'allow_custom' flag

# create FileSystemStore
fs = FileSystemSource("/path/to/stix2_data/", allow_custom=True)

# create TAXIICollectionSource
colxn = Collection('http://taxii_url')
ts = TAXIICollectionSource(colxn, allow_custom=True)