If you are reading this blog post via a 3rd party source it is very likely that many parts of it will not render correctly. Please view the post on signalscorps.com for the full interactive viewing experience.
In this post I will show you how to package your STIX Objects so that they can be shared with others and integrated with other software.
Note: this post is written for OASIS STIX version 2.1. The concepts discussed are not always correct for earlier versions of OASIS STIX.
The reason more-and-more companies are standardising their intelligence work on STIX 2.1 is partly due to its broad specification as covered in previous posts. In turn, other organisations and tools are now standardising on STIX 2.1.
Before you package your content into a STIX Bundle (more on that to follow), there are a few best practices I would like to share.
Data Marking Objects
Sharing of intelligence organisations is becoming increasingly important. Protocols (like TLP) are common place in defining who data can be shared with and how.
In STIX 2.1, Data Marking ("type": "marking-definition"
) STIX Meta Objects (SMOs) provide these designations.
Data Marking can be used in any STIX Object type including most commonly with SDOs, SCOs, and SROs.
Two marking definition types are defined in the STIX 2.1 specification:
Here is an example of me declaring a copyright "definition_type": "statement"
for an Indicator Object;
As you will see in the json representation, inside the Indicator SDOs object_marking_refs
Property I link it to the marking-definition--
SMO .
A TLP marking type can be achieved in much the same way, however this time the definition_type
is tlp
not statement
.
Here is an example of both a Statement and TLP definition_type
linked from an Indicator SDO.
It is very important to point out, TLP marking-definition--
s must use the 4 TLP SMOs exactly as define in the specification, including IDs;
Data Markings can cover an entire STIX SRO, SDO, or SCO (as Object Markings) shown in the previous two examples. They can also be written to cover just part of the Object (as Granular Markings).
The actual structure of the marking-definition
Object defining the type (TLP or Statement) remains unchanged.
However, the change happens inside the Object I want to apply the granular marking to. Instead of using the object_marking_refs
Property, I instead use the property granular_markings
.
Inside the granular_markings
Property I then define the marking_ref
, which points to the marking-definition
Object defining the marking, and a list of values under the selectors
Property. The selectors
Property is a list of fields (and specific field values in the case of lists), the marking-definition
should apply to;
"granular_markings": [
{
"marking_ref": "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed",
"selectors": [
"description"
]
},
{
"marking_ref": "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82",
"selectors": [
"indicator_types.[1]"
]
},
{
"marking_ref": "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da",
"selectors": [
"indicator_types.[0]",
"name",
"pattern"
]
}
Lets imagine an example where you might want to do this. My scenario focuses on a STIX producer, “Signals Corps Bank” who imposes granular markings on an Indicator object.
Before sharing the Indicator SDO, Signals Corps Bank selects a few TLP marking definitions to apply to the Properties inside the Indicator SDO.
Three marking-definition
Objects help restrict the usage of certain properties of the Indicator SDO based on its TLP marking type as follows;
marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed
- applies to the Indicator SDOs
description
fields - TLP for this
marking-definition
is Red
- applies to the Indicator SDOs
marking-definition--f88d31f6-486f-44da-b317-01333bde0b82
- applies to the Indicator SDOs
indicator_types.[1]
field. Note, 1 denotes the second item in theindicator_types
list (in this caseattribution
) – it is a zero-based list index - TLP for this
marking-definition
is Amber
- applies to the Indicator SDOs
marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da
- applies to the Indicator SDOs
indicator_types.[0]
,name
, andpattern
fields - TLP for this
marking-definition
is Green
- applies to the Indicator SDOs
You will also note that the Threat Actor uses the same marking-definition
(marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed
= TLP Red) as the Indicator Property uses for Granular Marking of the description field, however, the Threat Actor Object is using it globally to define the TLP level for the entire Object (all its properties).
Creating an Identity SDO
If you are creating content, you should usually attribute it to yourself (unless you wish to remain anonymous) using an Identity SDO using the global shared Property created_by_ref
. You can create your Identity SDO once, and reuse it for all future attribution.
Do not forget to use SROs and/or Object Property values to attribute the Object to you via the Identity SDO.
Here is an example for the organisation, Signals Corps;
Note: if creating an identity for yourself you should not include a circular reference to the same Identity Object in the created_by_ref
field. That is id
Property = created_by_ref
Property.
STIX Bundles
Throughout this series of posts I’ve been creating STIX Bundles to model the STIX Objects created on the graph.
A STIX Bundle is a .json
document that provides a wrapper mechanism for packaging a complete set of STIX content together.
The Properties of a STIX Bundle are simple. A Bundle has the Properties; type
, id
, and a list of STIX objects
it contains (SDOs, SCOs, SROs, SMOs, etc.)
To see the structure of a STIX Bundle, click “Download STIX 2.1 Bundle” in one of the graphs above.
The amount of data packed into a Bundle depends on a consumer.
Sometimes, in the case of report writing, it makes sense to package all the Objects into a single STIX Bundle to share (very similar to the Mandiant and FireEye reports shared in the first post).
If you are simply sharing bundles via GitHub, or though viewers (like I use), then it usually makes more sense to bundle all Objects into a single static bundle so external lookups do not need to be made.
In other cases, for example continual data sharing between consumer and producer, it makes more sense to ship Bundles with only new and updated Objects which can be cross-referenced and viewed alongside previously ingested Bundles.
How you deal with this depends largely on your consumers and how you give them access to your data, though in most intelligence sharing use-cases Bundles are usually generated with new content only.
Automating STIX 2.1 Content Creation
After reading the content over the last two months it is likely you want to start modelling some intelligence in STIX 2.1 and Bundle it up to share, if you have not already.
Luckily OASIS have built cti-python-stix2, a set of Python APIs that allow you to quickly start creating STIX 2.1 content.
In the final part of this series I will jump into how I used it to create the examples in these posts, and how to take them even further.
STIX 2.1 Certification (Virtual and In Person)
The content used in this post is a small subset of our full training material used in our STIX 2.1 training.
If you want to join a select group of certified STIX 2.1 professionals, subscribe to our newsletter below to be notified of new course dates.
Discuss this post

Never miss an update
Sign up to receive new articles in your inbox as they published.