Usage

Initialize a PySTIXView object to start building your graph. You can use the notebook option if you are going to use the library in a Jupyter Notebook.

from pystixview import PySTIXView

stix_view = PySTIXView(notebook=True)

Add a node

You can add a STIX object as graph node by passing a stix2 object, a string or a dict representing the object:

from stix2 import ThreatActor

threat_actor = ThreatActor(name="Adversary Bravo")
stix_view.add_node(threat_actor)
malware = """{
     "type": "malware",
     "spec_version": "2.1",
     "id": "malware--d1c612bc-146f-4b65-b7b0-9a54a14150a4",
     "created": "2015-04-23T11:12:34.760Z",
     "modified": "2015-04-23T11:12:34.760Z",
     "name": "Poison Ivy Variant d1c6",
     "malware_types": [
         "remote-access-trojan"
     ],
     "is_family": false,
     "kill_chain_phases": [
         {
             "kill_chain_name": "mandiant-attack-lifecycle-model",
             "phase_name": "initial-compromise"
         }
     ]
 }"""

stix_view.add_node(malware)

Supported STIX Object

PySTIXView supports the STIX Domain Object and Cyber Observable Object types:

  • STIX Domain Objects
    • AttackPattern
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/sdo/attack-pattern/square-flat.png
    • Campaign
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/sdo/campaign/square-flat.png
    • CourseOfAction
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/sdo/course-of-action/square-flat.png
    • Grouping
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/sdo/grouping/square-flat.png
    • Identity
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/sdo/identity/square-flat.png
    • Indicator
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/sdo/indicator/square-flat.png
    • Infrastructure
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/sdo/infrastructure/square-flat.png
    • IntrusionSet
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/sdo/intrusion-set/square-flat.png
    • Location
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/sdo/location/square-flat.png
    • Malware
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/sdo/malware/square-flat.png
    • MalwareAnalysis
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/sdo/malware-analysis/square-flat.png
    • Note
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/sdo/note/square-flat.png
    • ObservedData
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/sdo/observed-data/square-flat.png
    • Opinion
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/sdo/opinion/square-flat.png
    • Report
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/sdo/report/square-flat.png
    • ThreatActor
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/sdo/threat-actor/square-flat.png
    • Tool
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/sdo/tool/square-flat.png
    • Vulnerability
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/sdo/vulnerability/square-flat.png
  • STIX Cyber Observabel Object
    • AutonomousSystem
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/observable/autonomous-system/square-flat.png
    • DomainName
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/observable/domain-name/square-flat.png
    • EmailAddress
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/observable/email-address/square-flat.png
    • EmailMessage
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/observable/email-message/square-flat.png
    • File
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/observable/file/square-flat.png
    • IPv4Address
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/observable/ipv4-addr/square-flat.png
    • IPv6Address
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/observable/ipv6-addr/square-flat.png
    • MACAddress
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/observable/mac-addr/square-flat.png
    • NetworkTraffic
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/observable/network-traffic/square-flat.png
    • URL
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/observable/url/square-flat.png
    • UserAccount
      https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/observable/user-account/square-flat.png

Default Data Markings are also supported:

  • TLP_AMBER
    https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/generic/tlp-amber-square-flat.png
  • TLP_GREEN
    https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/generic/tlp-green-square-flat.png
  • TLP_WHITE
    https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/generic/tlp-white-square-flat.png
  • TLP_RED
    https://raw.githubusercontent.com/vincenzocaputo/PySTIXView/main/pystixview/icons/generic/tlp-red-square-flat.png

You can also add your custom STIX Object to the graph. See this section for details.

Using Bundles

A Bundle is a collection of STIX Objects. You can create a graph from a Bundle by using the function pystixview.PySTIXView.add_bundle():

stix_view = PySTIXView()
with open("threat-actor-leveraging-attack-patterns-and-malware.json", "r") as fd:
    stix_view.add_bundle(fd.read())

This feature is particularly suitable for handling a large number of STIX Objects, saved in JSON files or coming from TAXII servers or other sources. For example, you can use PySTIXView to display the graph of the STIX representation of a MISP Event, using the library MISPtoSTIX21Parser:

from pystixview import PySTIXView
from misp_stix_converter import MISPtoSTIX21Parser

# Get a MISPEvent object from your MISP instance
# ...

parser = MISPtoSTIX21Parser()
parser.parse_misp_event(event)
bundle = parser.bundle

stix_view = PySTIXView(notebook=True)
stix_view.add_bundle(bundle)
_images/misp_graph.png

Add a relationship

You can add a relationship between two nodes by providing a stix2 Relationship object, a string or dict representing the relationship.

relationship = {
    "type": "relationship",
    "spec_version": "2.1",
    "id": "relationship--d44019b6-b8f7-4cb3-837e-7fd3c5724b87",
    "created": "2020-02-29T18:18:08.661Z",
    "modified": "2020-02-29T18:18:08.661Z",
    "relationship_type": "uses",
    "source_ref": threat_actor['id'],
    "target_ref": "malware--d1c612bc-146f-4b65-b7b0-9a54a14150a4"
}

stix_view.add_relationship(relationship)

Show graph

Once you have added nodes to the graph and connected them via relationship, you can generate the HTML to render the graph. You can use the function pystixview.PySTIXView.save_graph() to save an HTML file or the function pystixview.PySTIXView.show_graph() to get the HTML code. The latter is especially useful within Jupyter Notebook, since the graph will be visible in the notebook via an iframe.

stix_view.show_graph('graph.html', width='500px', height='300px')
_images/graph.png

Clicking on a node will display the JSON content of the STIX Object:

_images/graph_selected.png

You can modify the visualization of the graph by using several options to filter and customize graph nodes. In particular, the style option let you to choose the look and feel of node icons. You can pick from the following styles:

  • square-flat (default)

  • square-dark

  • square-lite

  • noback-flat

  • noback-dark

  • round-flat

Custom STIX Object Types

You can add also custom STIX Objects as nodes to the graph, however a warning will be raised and a default icon will be used:

_images/custom_stix.png

It is recommended to “register” the custom STIX object by providing a custom icon (or a color). You can also select which field use as node label:

from stix2 import CustomObject, properties

stix_view.add_node("""{
    "type": "x-animal",
    "id": "x-animal-4c61fff5-1577-417b-9451-671a4aa6cfc9",
    "species": "lion",
    "animal_class": "mammal"
}""")
stix_view.show_graph('graph.html', width='100%', height='600px')
_images/custom_stix_ok.png

You can as well use stix2 CustomObject to add the nodes to the graph:

from stix2 import CustomObject, properties
@CustomObject('x-animal', [
   ('species', properties.StringProperty(required=True)),
   ('animal_class', properties.StringProperty()),
])
class Animal(object):
  def __init__(self, animal_class=None, **kwargs):
     if animal_class and animal_class not in ['mammal', 'bird', 'fish', 'reptile']:
         raise ValueError("'%s' is not a recognized class of animal." % animal_class)

stix_view.add_custom_stix_type('x-animal', 'animal-icon.png', label_name="species")
animal = Animal(species="lion",
            animal_class="mammal")

stix_view.add_node(animal)

stix_view.show_graph('graph.html', width='100%', height='600px')