Tip: Easily use JSON fields in Sentinel
Published Jul 22 2019 05:15 PM 21.3K Views
Microsoft

One of the great features with Azure Sentinel is that you can ingest any type of data and take care of parsing it later on at query time. Specifically, events originating from cloud sources often include JSON compound elements that provide wealthy information about the event. This is a far cry from traditional SIEM systems that support a rigid event format and, in many cases, require reducing events to fit in the schema. Another common source of JSON data in Azure Sentinel would be enrichment data collected using playbooks as demonstrated by Tiander Turpin here.

 

This brings us to the question of how to write a query to use JSON fields. Sentinel’s query language, KQL, uses the parse_json function to provide access to JSON field elements. However, when the JSON structure becomes deeper, using this function can become cumbersome. Luckily, Sentinel provides new tools to help you write those queries.

 

Let’s use Microsoft Cloud App Security (MCAS) alerts as an example. Using the following query, we get MCAS alerts on impossible travel:

SecurityAlert

| where ProviderName == "MCAS"

| where DisplayName == "Impossible travel activity"

| limit 10

1.png

 

Expanding one of the events, we can see that the countries Alex visited are located in the Extended Properties JSON compound field:

 

2.png

 

To use the countries just visited value, we can use the ellipsis on the left side of it automatically add a JSON parsing function to our query. Selecting the include option updates the query automatically to the one below:

 

3.png

 

SecurityAlert

| where ProviderName == "MCAS"

| where DisplayName == "Impossible travel activity"

| limit 10 

| where parse_json(ExtendedProperties).Countries == "AU, DE, FR, GB, JP, US"

 

However, since the Counties field is a list, include and exclude might not be particularly useful as they add a condition that would require the entire list of counties to be identical. You can change the “==” or “!=” operators automatically generated to a contains or !contains operators:

SecurityAlert

| where ProviderName == "MCAS"

| where DisplayName == "Impossible travel activity"

| limit 10

| where parse_json(ExtendedProperties).Countries contains "AU"

 

A better option would be to use the extend column option, which allows to filter further and process the new field and also ensures it is presented as a field in the results. Using extend column instead of include, the query is automatically updated as follows:

SecurityAlert

| where ProviderName == "MCAS"

| where DisplayName == "Impossible travel activity"

| limit 10

| extend Countries_ = tostring(parse_json(ExtendedProperties).Countries)

Will result in the following output, adding a Countries_ field to the result set for easy viewing:

 

4.png

2 Comments
Brass Contributor

@Ofer_Shezaf  Good one. 

Can you please share some information on how can we extract or parse the entities data when no of values within the entities are not constant.

 

Thanks.

Microsoft

@PrashTechTalk : use the mv-expand operator. It will creates a separate row in the result set for each array value, enabling processing the array using regular KQL table processing.  

Version history
Last update:
‎Jul 24 2019 06:30 AM
Updated by: