While indicators of compromise represent intelligence assertions behind attacks, raw observed information help formulate the basis behind this intelligence. In many cases, it may be beneficial for organizations to share this observed data among each other. Similar to indicators, sightings can contain references to observed data objects that were spotted on other organizations’ networks and could signal information about a type of malware present. This may potentially allow for further intelligence assertions to be made based on this sighted raw information.

Scenario

This scenario consists of two cyber threat companies, Pym and Oscorp, who share threat intelligence with one another. Pym Technologies originally shared a Malware STIX Domain Object (SDO) with Oscorp. Oscorp later believes they have spotted this Malware object on their own network based upon some captured observed data which contains hashes that match the malware as well as registry keys that the malware created. To represent this, Oscorp issues a Sighting STIX Relationship Object (SRO) that holds references to these observed data and relays that this could be a sighting-of this particular malware.

Data model

In this example, there are two Identity STIX Domain Objects (SDOs) used for the two companies: Pym and Oscorp. The Identity objects document relevant information about the two organizations, such as what sector they are in and relevant contact information. Both organizations are producers and consumers of STIX intelligence, so their id’s can be referenced within objects using the created_by_ref property to indicate they are the originators of the STIX objects they generate. It is worth noting that Identity SDO’s can also be used to represent individuals, attack targets, government agencies, and groups, to name a few.

The Identity objects at the very minimum need a value for the required name property. In this example, the identity_class property is also used, and it is important for categorizing the type of identity Pym and Oscorp represen: organization, in this case. This value comes from the identity class open vocabulary, which contains suggested values for labeling Identities.

Pym Technologies first created a Malware SDO to represent details about the type of malware in this scenario. This specific malware type is labeled as a remote-access-trojan, and is an executable disguised as a pdf file that creates multiple registry keys. Pym then shared this intelligence with Oscorp.

Oscorp Industries, which now has this Malware object, believes it has seen this malware on its own networks and created a Sighting object to represent this. The Sighting SRO is a special type of STIX relationship that contains properties about the object seen such as the id of the Malware SDO (with sighting_of_ref), a count property that indicates the number of times this malware was seen, as well as timestamps for when it was first and last seen. In addition, a listing of Observed-Data ids is included to communicate any necessary information that may support the sighting of this malware.

Observed Data SDO’s contain references to cyber observables (e.g. IP addresses, files, URL’s) that were captured on systems and networks. In this scenario, Oscorp observed both file and registry key information. They can model this information within 2 different Observed-Data objects. Although you are able to include references to multiple cyber observable objects within one Observed-Data instance, the cyber observables must be related to each other. In this case, the file and registry data are not directly related so their references are contained in separate Observed-Data instances. You can read more about STIX objects and cyber observable objects, which are covered in parts 4 and 6 of the STIX 2.1 specification, respectively.

For Observed-Data objects, either the object_refs (preferred) or objects (deprecated) property must be included, and all other Observed-Data specific properties are required. So for each of these objects, Oscorp had to provide when each instance was first_observed and last_observed, as well as a count (number_observed) of the number of times the data was observed. In addition, they can provide references to the actual cyber observable objects in the object_refs property. The first Observed-Data instance in this example (Observed Data 1 in the diagram below) contains information about the file that was seen. So, data like a listing of hashes, the file’s name, and its size were included to represent the file. In the second Observed-Data instance, Oscorp models Windows Registry values such as the registry key that the suspected malware created.

Finally, it is worth mentioning that none of the objects in this scenario use the standard Relationship SRO which is typically used to relate objects with one another. The Sighting SRO is used instead for the sighting of the Malware object and all other relationships in the diagram below are embedded within the objects. For instance, the Sighting object contains several embedded relationships including what was observed, who the object was created by, and where the sighting was seen.

A diagram of this scenario is depicted below (An interactive version can be found here):

Sighting of Observed-data

Further Reading

To read more about the objects in this example as well as common properties and vocabularies, check out the links below:

Implementation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
{
    "type": "bundle",
    "id": "bundle--1affa123-0a4f-4fc5-81c6-fc1b058f9e44",
    "objects": [
        {
            "type": "identity",
            "spec_version": "2.1",
            "id": "identity--7865b6d2-a4af-45c5-b582-afe5ec376c33",
            "created": "2013-04-14T13:07:49.812Z",
            "modified": "2013-04-14T13:07:49.812Z",
            "name": "Pym Technologies",
            "identity_class": "organization",
            "sectors": [
                "technology"
            ],
            "contact_information": "hank@pymtech.com"
        },
        {
            "type": "identity",
            "spec_version": "2.1",
            "id": "identity--987eeee1-413a-44ac-96cc-0a8acdcc2f2c",
            "created": "2017-01-14T13:07:49.812Z",
            "modified": "2017-01-14T13:07:49.812Z",
            "name": "Oscorp Industries",
            "identity_class": "organization",
            "sectors": [
                "technology"
            ],
            "contact_information": "norman@oscorp.com"
        },
        {
            "type": "malware",
            "spec_version": "2.1",
            "id": "malware--ae560258-a5cb-4be8-8f05-013d6712295f",
            "created_by_ref": "identity--7865b6d2-a4af-45c5-b582-afe5ec376c33",
            "created": "2014-02-20T09:16:08.989Z",
            "modified": "2014-02-20T09:16:08.989Z",
            "name": "Online Job Site Trojan",
            "description": "Trojan that is disguised as the executable file resume.pdf., it also creates a registry key.",
            "malware_types": [
                "remote-access-trojan"
            ],
            "is_family": false
        },
        {
            "type": "file",
            "id": "file--364fe3e5-b1f4-5ba3-b951-ee5983b3538d",
            "spec_version": "2.1",
            "hashes": {
                "MD5": "1717b7fff97d37a1e1a0029d83492de1",
                "SHA-1": "c79a326f8411e9488bdc3779753e1e3489aaedea"
            },
            "size": 83968,
            "name": "resume.pdf"
        },
        {
            "type": "observed-data",
            "spec_version": "2.1",
            "id": "observed-data--cf8eaa41-6f4c-482e-89b9-9cd2d6a83cb1",
            "created_by_ref": "identity--987eeee1-413a-44ac-96cc-0a8acdcc2f2c",
            "created": "2017-02-28T19:37:11.213Z",
            "modified": "2017-02-28T19:37:11.213Z",
            "first_observed": "2017-02-27T21:37:11.213Z",
            "last_observed": "2017-02-27T21:37:11.213Z",
            "number_observed": 1,
            "object_refs": [
                "file--364fe3e5-b1f4-5ba3-b951-ee5983b3538d"
            ]
        },
        {
            "type": "sighting",
            "spec_version": "2.1",
            "id": "sighting--779c4ae8-e134-4180-baa4-03141095d971",
            "created_by_ref": "identity--987eeee1-413a-44ac-96cc-0a8acdcc2f2c",
            "created": "2017-02-28T19:37:11.213Z",
            "modified": "2017-02-28T19:37:11.213Z",
            "first_seen": "2017-02-28T19:07:24.856Z",
            "last_seen": "2017-02-28T19:07:24.857Z",
            "count": 1,
            "sighting_of_ref": "malware--ae560258-a5cb-4be8-8f05-013d6712295f",
            "observed_data_refs": [
                "observed-data--cf8eaa41-6f4c-482e-89b9-9cd2d6a83cb1",
                "observed-data--a0d34360-66ad-4977-b255-d9e1080421c4"
            ],
            "where_sighted_refs": [
                "identity--987eeee1-413a-44ac-96cc-0a8acdcc2f2c"
            ]
        },
        {
            "type": "windows-registry-key",
            "id": "windows-registry-key--16b80d14-d574-5620-abad-10ff304b1c26",
            "spec_version": "2.1",
            "key": "HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Services\\WSALG2"
        },
        {
            "type": "observed-data",
            "spec_version": "2.1",
            "id": "observed-data--a0d34360-66ad-4977-b255-d9e1080421c4",
            "created_by_ref": "identity--987eeee1-413a-44ac-96cc-0a8acdcc2f2c",
            "created": "2017-02-28T19:37:11.213Z",
            "modified": "2017-02-28T19:37:11.213Z",
            "first_observed": "2017-02-27T21:37:11.213Z",
            "last_observed": "2017-02-27T21:37:11.214Z",
            "number_observed": 1,
            "object_refs": [
                "windows-registry-key--16b80d14-d574-5620-abad-10ff304b1c26"
            ]
        }
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
from stix2.v21 import (File, Identity, Malware, ObservedData, Sighting, WindowsRegistryKey, Bundle)

identityOscorp = Identity(
    id="identity--987eeee1-413a-44ac-96cc-0a8acdcc2f2c",
    created="2017-01-14T13:07:49.812Z",
    modified="2017-01-14T13:07:49.812Z",
    name="Oscorp Industries",
    identity_class="organization",
    contact_information="norman@oscorp.com",
    sectors=["technology"],
    spec_version="2.1",
    type="identity"
)

identityPym = Identity(
    id="identity--7865b6d2-a4af-45c5-b582-afe5ec376c33",
    created="2013-04-14T13:07:49.812Z",
    modified="2013-04-14T13:07:49.812Z",
    name="Pym Technologies",
    identity_class="organization",
    contact_information="hank@pymtech.com",
    sectors=["technology"],
    spec_version="2.1",
    type="identity"
)

malware = Malware(
    id="malware--ae560258-a5cb-4be8-8f05-013d6712295f",
    created="2014-02-20T09:16:08.989Z",
    modified="2014-02-20T09:16:08.989Z",
    created_by_ref=identityPym.id,
    name="Online Job Site Trojan",
    description="Trojan that is disguised as the executable file resume.pdf., it also creates a registry key.",
    malware_types=["remote-access-trojan"],
    spec_version="2.1",
    type="malware",
    is_family="false"
)

fileMalicious = File(
    hashes={
        "MD5": "1717b7fff97d37a1e1a0029d83492de1",
        "SHA-1": "c79a326f8411e9488bdc3779753e1e3489aaedea"
    },
    name="resume.pdf",
    size=83968,
    id="file--364fe3e5-b1f4-5ba3-b951-ee5983b3538d",
    spec_version="2.1"
)

observedDataFile = ObservedData(
    id="observed-data--cf8eaa41-6f4c-482e-89b9-9cd2d6a83cb1",
    created="2017-02-28T19:37:11.213Z",
    modified="2017-02-28T19:37:11.213Z",
    first_observed="2017-02-27T21:37:11.213Z",
    last_observed="2017-02-27T21:37:11.213Z",
    number_observed=1,
    created_by_ref=identityOscorp.id,
    object_refs=[
        "file--364fe3e5-b1f4-5ba3-b951-ee5983b3538d"
    ],
    spec_version="2.1",
    type="observed-data"
)

winRegKey = WindowsRegistryKey(
    key="HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Services\\WSALG2",
    spec_version="2.1",
    id="windows-registry-key--16b80d14-d574-5620-abad-10ff304b1c26"
)

observedDataRegKey = ObservedData(
    id="observed-data--a0d34360-66ad-4977-b255-d9e1080421c4",
    created="2017-02-28T19:37:11.213Z",
    modified="2017-02-28T19:37:11.213Z",
    first_observed="2017-02-27T21:37:11.213Z",
    last_observed="2017-02-27T21:37:11.213Z",
    number_observed=1,
    created_by_ref=identityOscorp.id,
    object_refs=[
        "windows-registry-key--16b80d14-d574-5620-abad-10ff304b1c26"
    ],
    spec_version="2.1",
    type="observed-data"
)

sighting = Sighting(
    id="sighting--779c4ae8-e134-4180-baa4-03141095d971",
    created_by_ref=identityOscorp.id,
    created="2017-02-28T19:37:11.213Z",
    modified="2017-02-28T19:37:11.213Z",
    first_seen="2017-02-28T19:07:24.856Z",
    last_seen="2017-02-28T19:07:24.857Z",
    count=1,
    sighting_of_ref="malware--ae560258-a5cb-4be8-8f05-013d6712295f",
    where_sighted_refs=["identity--987eeee1-413a-44ac-96cc-0a8acdcc2f2c"],
    observed_data_refs=["observed-data--cf8eaa41-6f4c-482e-89b9-9cd2d6a83cb1", "observed-data--a0d34360-66ad-4977-b255-d9e1080421c4"],
    spec_version="2.1",
    type="sighting"
)

bundle = Bundle(objects=[identityPym, identityOscorp, malware, observedDataFile, observedDataRegKey, sighting])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
from stix2.v21 import (Bundle)

for obj in bundle.objects:
    if obj == identityPym:
        print("------------------")
        print("== IDENTITY ==")
        print("------------------")
        print("ID: " + obj.id)
        print("Created: " + str(obj.created))
        print("Modified: " + str(obj.modified))
        print("Name: " + obj.name)
        print("Identity Class: " + obj.identity_class)
        print("Sectors: " + str(obj.sectors))
        print("Contact Information: " + obj.contact_information)

    elif obj == identityOscorp:
        print("------------------")
        print("== IDENTITY ==")
        print("------------------")
        print("ID: " + obj.id)
        print("Created: " + str(obj.created))
        print("Modified: " + str(obj.modified))
        print("Name: " + obj.name)
        print("Identity Class: " + obj.identity_class)
        print("Sectors: " + str(obj.sectors))
        print("Contact Information: " + obj.contact_information)

    elif obj == malware:
        print("------------------")
        print("== MALWARE ==")
        print("------------------")
        print("ID: " + obj.id)
        print("Created: " + str(obj.created))
        print("Modified: " + str(obj.modified))
        print("Name: " + obj.name)
        print("Type: " + obj.type)
        print("Malware Types: " + str(obj.malware_types))
        print("Is Family:" + str(obj.is_family))


    elif obj == observedDataFile:
        print("------------------")
        print("== OBSERVED DATA ==")
        print("------------------")
        print("ID: " + obj.id)
        print("Created: " + str(obj.created))
        print("Modified: " + str(obj.modified))
        print("Created by Ref: " + obj.created_by_ref)
        print("First Observed: " + str(obj.first_observed))
        print("Last Observed: " + str(obj.last_observed))
        print("Number Observed: " + str(obj.number_observed))
        print("Object Refs: " + str(obj.object_refs))

    elif obj == observedDataRegKey:
        print("------------------")
        print("== OBSERVED DATA ==")
        print("------------------")
        print("ID: " + obj.id)
        print("Created: " + str(obj.created))
        print("Modified: " + str(obj.modified))
        print("Created by Ref: " + obj.created_by_ref)
        print("First Observed: " + str(obj.first_observed))
        print("Last Observed: " + str(obj.last_observed))
        print("Number Observed: " + str(obj.number_observed))
        print("Object Refs: " + str(obj.object_refs))

    elif obj == sighting:
        print("------------------")
        print("== SIGHTING ==")
        print("------------------")
        print("ID: " + obj.id)
        print("Created: " + str(obj.created))
        print("Modified: " + str(obj.modified))
        print("Type: " + obj.type)
        print("Created by Ref: " + obj.created_by_ref)
        print("First Seen: " + str(obj.first_seen))
        print("Last Seen: " + str(obj.last_seen))
        print("Count: " + str(obj.count))
        print("Sighting of Ref: " + obj.sighting_of_ref)
        print("Observed Data Ref: " + str(obj.observed_data_refs))
        print("Where Sighted Refs: " + str(obj.where_sighted_refs))

    elif obj == fileMalicious:
        print("------------------")
        print("== FILE ==")
        print("------------------")
        print("ID: " + obj.id)
        print("Type: " + obj.type)
        print("Hashes: " + str(obj.hashes))
        print ("Name: " + obj.name)
        print ("Size: " + str(obj.size))

    elif obj == winRegKey:
        print("------------------")
        print("== WINDOWS REGISTRY KEY ==")
        print("------------------")
        print("ID: " + obj.id)
        print("Type: " + obj.type)
        print("Key: " + obj.key)