Memory

The Memory suite consists of MemoryStore, MemorySource, and MemorySink. Under the hood, the Memory suite points to an in-memory dictionary. Similarly, the MemoryStore is a just a wrapper around a paired MemorySource and MemorySink; as there is quite limited uses for just a MemorySource or a MemorySink, it is recommended to always use MemoryStore. The MemoryStore is intended for retrieving/searching and pushing STIX content to memory. It is important to note that all STIX content in memory is not backed up on the file system (disk), as that functionality is encompassed within the FileSystemStore. However, the Memory suite does provide some utility methods for saving and loading STIX content to disk. MemoryStore.save_to_file() allows for saving all the STIX content that is in memory to a json file. MemoryStore.load_from_file() allows for loading STIX content from a JSON-formatted file.

Memory API

A note on adding and retreiving STIX content to the Memory suite: As mentioned, under the hood the Memory suite is an internal, in-memory dictionary. STIX content that is to be added can be in the following forms: python-stix2 objects, (Python) dictionaries (of valid STIX objects or Bundles), JSON-encoded strings (of valid STIX objects or Bundles), or a (Python) list of any of the previously listed types. MemoryStore actually stores and retrieves STIX content as python-stix2 objects.

A note on load_from_file(): For load_from_file(), STIX content is assumed to be in JSON form within the file, as an individual STIX object or in a Bundle. When the JSON is loaded, the STIX objects are parsed into python-stix2 objects before being stored in the in-memory dictionary.

A note on save_to_file(): This method dumps all STIX content that is in the MemoryStore to the specified file. The file format will be JSON, and the STIX content will be within a STIX Bundle.

Memory Examples

MemoryStore

[3]:
from stix2 import MemoryStore, Indicator

# create default MemoryStore
mem = MemoryStore()

# insert newly created indicator into memory
ind = Indicator(description="Crusades C2 implant",
                pattern_type="stix",
                pattern="[file:hashes.'SHA-256' = '54b7e05e39a59428743635242e4a867c932140a999f52a1e54fa7ee6a440c73b']")

mem.add(ind)

# for visual purposes
print(mem.get(ind.id).serialize(pretty=True))

[3]:
{
    "type": "indicator",
    "spec_version": "2.1",
    "id": "indicator--96120abd-f767-4292-b8b0-b739749e03b6",
    "created": "2020-06-26T18:28:55.582226Z",
    "modified": "2020-06-26T18:28:55.582226Z",
    "description": "Crusades C2 implant",
    "pattern": "[file:hashes.'SHA-256' = '54b7e05e39a59428743635242e4a867c932140a999f52a1e54fa7ee6a440c73b']",
    "pattern_type": "stix",
    "pattern_version": "2.1",
    "valid_from": "2020-06-26T18:28:55.582226Z"
}
[4]:
from stix2 import Malware

# add multiple STIX objects into memory
ind2 = Indicator(description="Crusades stage 2 implant",
                 pattern_type="stix",
                 pattern="[file:hashes.'SHA-256' = '70fa62fb218dd9d936ee570dbe531dfa4e7c128ff37e6af7a6a6b2485487e50a']")
ind3 = Indicator(description="Crusades stage 2 implant variant",
                 pattern_type="stix",
                 pattern="[file:hashes.'SHA-256' = '31a45e777e4d58b97f4c43e38006f8cd6580ddabc4037905b2fad734712b582c']")
mal = Malware(malware_types=["rootkit"], name="Alexios", is_family=False)

mem.add([ind2,ind3, mal])

# for visual purposes
print(mem.get(ind3.id).serialize(pretty=True))
[4]:
{
    "type": "indicator",
    "spec_version": "2.1",
    "id": "indicator--dd5a0203-356d-415c-a118-fb6b0eae9de0",
    "created": "2020-06-26T18:28:58.047811Z",
    "modified": "2020-06-26T18:28:58.047811Z",
    "description": "Crusades stage 2 implant variant",
    "pattern": "[file:hashes.'SHA-256' = '31a45e777e4d58b97f4c43e38006f8cd6580ddabc4037905b2fad734712b582c']",
    "pattern_type": "stix",
    "pattern_version": "2.1",
    "valid_from": "2020-06-26T18:28:58.047811Z"
}
[5]:
from stix2 import Filter

mal = mem.query([Filter("malware_types","=", "rootkit")])[0]
print(mal.serialize(pretty=True))
[5]:
{
    "type": "malware",
    "spec_version": "2.1",
    "id": "malware--6cee28b8-4d42-4e72-bd77-ea47897672c0",
    "created": "2020-06-26T18:28:58.049244Z",
    "modified": "2020-06-26T18:28:58.049244Z",
    "name": "Alexios",
    "malware_types": [
        "rootkit"
    ],
    "is_family": false
}

load_from_file() and save_to_file()

[7]:
mem_2 = MemoryStore()

# save (dump) all STIX content in MemoryStore to json file
mem.save_to_file("path_to_target_file.json")

# load(add) STIX content from json file into MemoryStore
mem_2.load_from_file("path_to_target_file.json")

report = mem_2.get("malware--6cee28b8-4d42-4e72-bd77-ea47897672c0")

# for visual purposes
print(report.serialize(pretty=True))
[7]:
{
    "type": "malware",
    "spec_version": "2.1",
    "id": "malware--6cee28b8-4d42-4e72-bd77-ea47897672c0",
    "created": "2020-06-26T18:28:58.049244Z",
    "modified": "2020-06-26T18:28:58.049244Z",
    "name": "Alexios",
    "malware_types": [
        "rootkit"
    ],
    "is_family": false
}