MSTICPy v1.0.0 and Jupyter Notebooks for CyberSec

With the recent release of v 1.0.0 of MSTICPy we thought it was a good time to do an overview article. This is based on an article in the Azure Sentinel Technical Community blog but since that one focuses on MSTICPy’s use in Azure Sentinel and MSTICPy is ostensibly SIEM-agnostic we thought it would be good to do another version of it here.

What is MSTICPy?

The goals of MSTICPy are to:

  1. Simplify the process of creating and using notebooks for security analysis by providing building-blocks of key functionality.
  2. Improve the usability of notebooks by reducing the amount of code needed in notebooks.
  3. Make the functionality open and available to all, to both use and contribute to.

1000 feet view

  • Data Acquisition — is all about getting security data into the notebook. It includes data providers and pre-built queries that allow easy access to several security data stores including Azure Sentinel, Microsoft Defender, Splunk and Microsoft Graph. There are also modules that deal with saving and retrieving files from Azure blob storage and uploading data to Azure Sentinel and Splunk.
  • Data Enrichment — focuses on components such as threat intelligence and geo-location lookups that provide additional context to events found in the data. It also includes Azure APIs to retrieve details about Azure resources such as virtual machines and subscriptions.
  • Data Analysis — packages here focus on more advanced data processing: clustering, time series analysis, anomaly identification, base64 decoding and Indicator of Compromise (IoC) pattern extraction. Another component that we include here but really spans all of the first three categories is pivot functions — these give access to many MSTICPy functions via entities (for example, all IP address related functions are accessible as methods of the IpAddress entity class.)
  • Visualization — this includes components to visualize data or results of analyses such as: event timelines, process trees, mapping, morph charts, and time series visualization. Also included under this heading are a large number of notebook widgets that help speed up or simplify tasks such as setting query date ranges and picking items from a list. Also included here are a number of browsers for complex data (like the threat intel and alert browsers) or to help you navigate internal functionality (like the query and pivot function browsers).

We’ll cover a lot the things we just mentioned later in the article.

Companion Notebook

The notebook is available here.

Notebook Initialization

Most of our notebooks include a more-or-less identical setup sections at the beginning. These do three things:

  1. Checks the Python and MSTICPy versions and updates the latter if needed.
  2. Imports MSTICPy components.
  3. Loads and authenticates a query provider to be able to start querying data.

The following cell includes the first two of these:

If you see warnings in the output from the cell about configuration sections missing you should check out Getting Started documentation. Even if you are not running in Azure Sentinel, you may also find these two notebooks useful:

The utils.check_versions() function is really aimed at checking and tweaking the notebooks environment in Azure ML notebooks. If you’re running the notebook elsewhere then you can safely ignore this.

The init_notebook function automates a lot of MSTICPy import statements and checks to see that your configuration looks healthy.

The third part of the initialization loads the data provider (which is the interface to query data) and authenticates to your data source. In this example, we’re using the Azure Sentinel data provider.

Assuming you have your configuration set up correctly, this will usually take you through the authentication sequence, including any two-factor authentication required.

Wait! I don’t have a SIEM to query data from

You can also obtain a lot of very interesting attack data samples from the Open Threat Research Forge’s brilliant Mordor project. (MSTICPy has a data provider to help you search for a download samples from Mordor).

Data Queries

MSTICPy has many pre-defined queries for Azure Sentinel (as well as for other providers). You can choose to run one of these predefined queries or write your own. This list of queries is usually up-to-date but the code itself is the real authority (since we add new queries frequently). The easiest way to see the available queries is with the query browser. This shows the queries grouped by category and lets you view usage/parameter information for each query.

There is also a command-line equivalent function to the browser — qry_prov.list_queries().

Timespans

One thing you can see from this screen shot is that the data is returned as a pandas DataFrame. pandas is a package that is extremely popular in the data science community. MSTICPy uses it extensively as a universal data interchange format between different components. We’ll see more examples of DataFrames as we move through the article.

Although there are a lot of built-in queries, there will always be cases where you need something different. There are a couple of approaches:

  1. Most queries will take an optional parameter add_query_items which allows you to tack on (some might say “inject”!) arbitrary KQL (for Azure Sentinel queries) to the query.
  2. You can write a query from scratch as a string and just execute it.

These options are shown below in these two examples.

Visualizing Data

Event Timelines

MSTICPy makes extensive use of the interactive graphics of Bokeh. These charts can be panned and zoomed. Each event also has a hover-over tool-tip containing summary information about the event (the summary is derived from the source_columns parameter list).

Process Tree

Like the timeline, the process tree supports panning, zooming, hover details and has an optional data table viewer (you need to specify show_table=True when calling the function).

Alert Viewer

This example combines both the timeline viewer and the SelectAlert browser.

Data Enrichment with Threat Intelligence, WhoIs and GeoIP

This example shows calling a method of the IpAddress entity class to get WhoIs information for an IP address.

Although the whois feature is available as a standalone function, we’ve used a pivot function of the IpAddress class here. To do this we needed to load the Pivot class.

Side note — Pivot functions

Wait — what is an Entity?

An entity is essentially a “noun” in the CyberSec world — for example: an IP Address, host, URL, account, etc. They are typically things that do stuff or have stuff done to them. Entities will always have one or more properties that identify the entity and might also have additional context properties. For example, an IpAddress entity has its primary Address property and it might also have contextual properties like geo-location or ASN data.

Pivot functions are “verbs” to the entities “nouns”. They perform investigative actions (like data queries) on the entity and return a result. The Host entity class, for example, has data queries that retrieve process or logon events logged for that host. The IpAddress entity has functions to lookup its geo-location or query information about the address from threat intelligence providers.

Pivot functions are not statically coded into the entity classes. Instead, the pivot subsystem harvests pivot functions from available queries and components and dynamically adds them to the entities. This gives us a lot of flexibility to add new functions as the features of MSTICPy evolve. It also allows you to use functions from third party libraries or write your own functions and expose them as pivot functions.

How do you find what pivot functions (and even what entities) are available? The easiest way to view the entities, their pivot functions and the help associated with each function is to use the Pivot browser (similar to the query browser shown earlier).

Being grouped with their respective entities makes the pivot functions easy find (compared with hunting through documents to find the right module or function to import). Pivot functions are grouped into related sub-containers of the entity — so, all AzureSentinel queries have the form entity.AzureSentinel.query_function()

Another advantage of pivot functions (over standalone functions) is that they have a homogeneous interface. They will all accept inputs as single values, lists of values or values stored in DataFrames. They also always return their results as DataFrames.

Back to Enrichment

We then display the results output by this pipeline from (the last data tagged on is from the threat intel providers) in another special-purpose viewer — the TI browser. We’ll see this again a little later.

Here is an example of a more traditional “pipeline” — i.e. just good old Python function calls — rather than using pandas. It’s a bit clunkier but you can see more clearly what is going on in each step. Even if your plan is to produce a pipeline like the previous example, it’s a good idea to start with individual function calls and temporary variables until you get bugs ironed out.

The sequence below stitches together the base64 decoder, IoC pattern extractor and threat intel lookup that we saw previously. It’s taking an obfuscated PowerShell command line and extracting and examining the contents found in the decoded string. Finally, it displays the TI results in the TI browser.

We might also want to know where this IP address is physically located. We can do that by using our geo-location enrichment and displaying the results on a map.

Using advanced analysis (aka simple machine learning)

First we’ll show the time series decomposition and visualization component. This works by determining regular patterns of bulk events (think of outbound network byte counts or logon failures) and then identifies outliers to this pattern with a simple statistical calculation.

You can see the daily cadence network traffic and the presence of two outlying events on 7–11 (the date, not the store).

Where the data is more complex than bulk counts, we can use another anomaly identification technique using Markov Chains. Markov chains is a technique used to predict the future probability of something occurring given the probability of things that happened previously.

Here we are using it to analyze Office 365 data. We will build a model to determine the probability of specific sequences of actions and then identify rare sequences that deviate from this base probability. Office activity data is first grouped into sessions based on user name and source IP address. The probability of a given sequence of actions within a session is measured during the creation of the model. For example, it would be very common to see actions like opening emails, reading a few files, etc. An atypical session — that reads hundreds of files or performs unusual actions like setting a mail forwarding rule or delegating control of a mailbox — would be much less probable and so would detectable.

(the full code for this is given in the notebook)

There is clearly one session that stands out from the crowd in terms of the unusual actions seen in that session. We can use the rarity score (the inverse of the probability) to quickly filter out the other sessions and see what was happening. In this case, the event revealed a series of unexpected privilege assignment actions.

Documentation and Resources

Conclusion

Take-aways and actions.

  • Second would be install MSTICPy and kick the tires. We are always looking for feedback on what does and doesn’t work and are always open to requests or suggestions for new features.
  • Read the docs.
  • If you’re feeling adventurous, consider contributing to MSTICPy. These could be ideas that you have that you think would be helpful to the CyberSec community. If you’re a bit stuck for ideas but love security and Python coding, we have a few ideas of our own and way too few people to implement them.
  • File an issue, feature request, create a PR or just poke around the code on our GitHub repo.
  • Read a summary of the latest release.
  • Follow me (@ianhellen), Pete (@MSSPete) and Ashwin (@ashwinpatil) on Twitter.
  • You can also reach us at msticpy@microsoft.com

This is the account of the Microsoft Threat Intelligence Center (MSTIC).