Cybersecurity continues to be a growing concern for organizations and their board of directors. If there is an area of increased spend within IT departments, it is usually in the area of cybersecurity. Regardless of whether an organization has increased budgets or not, they should be looking to optimize that spend and use their resources as efficiently as possible.
Microsoft has made a lot of significant investments in cybersecurity tools recently including Azure Security Center, Windows Defender ATP, Azure Active Directory Identity Protection, Azure Information Protection (preview) and Cloud App Security. All of these security tools are now emitting security events through the Microsoft Graph Security APIs. In addition, Microsoft is planning on including support for Microsoft Intune, Office 365, Azure Advanced Threat Protection and partner solutions. All of these tools provide intelligent security solutions that reduce your risk of breaches or the impact of a breach if an organization invests the resources to take advantage of what these tools provide.
One challenge that does exist, when leveraging all of these Microsoft’s tools, is they are hosted in different portals which creates some inefficiencies as security personnel needs to jump back and forth between the portals.
To address the need to perform a lot of manual checks, Microsoft has exposed this critical security information behind a new API called Microsoft Graph Security API.
What is even better is they have exposed this API as an easy to consume connector for Azure Logic Apps, Microsoft Flow, and PowerApps.
Prerequisites
In order to use this connector within your organization, an administrator must first provide consent, which is part of the Microsoft Graph Security Authentication requirements. To address this requirement, we can have an administrator create a connection within Azure Logic Apps.
Supported Actions
The Microsoft documentation, calls out support for the following actions from the Microsoft Graph Security connector. Using these actions provides the opportunity to build out holistic detection and response workflows.
Get alerts – Use this action to get a list of alerts filtered on one or more alert properties. For example, get a list of alerts with Provider equals Azure Security Center or Palo Alto Networks.
Get alert by ID – Use this action to get a specific alert by alert id property.
Update alert – Update a specific alert by specifying the alert id property. Refer to the list of the editable properties of alerts to ensure required and editable properties are passed in your request. For example, you can update alert assigned to the property to assign the alert to a security analyst for investigations.
Create subscriptions – Use this action to create a Graph webhook subscription that notifies you of any changes, filtered to certain types of alerts you are interested in. For example, you can create a subscription that notifies you of high severity alerts.
Get active subscriptions – Use this action to get a list of unexpired subscriptions to manage the list of subscriptions
Update subscription – Update your subscription by specifying the subscription id. For example, you can update the expiration DateTime property of the subscription to extend the subscription.
Delete subscription – Delete your subscription by specifying the subscription id.
Scenario
For the purpose of this blog post, we are going to keep things pretty simple and just focus on the Get alerts action. Using this action, we will fetch new alerts based upon a timestamp, parse the response and then post a message into a Microsoft Team channel where a security operations team can monitor these alerts.
Naturally, a team will want to spend some time with all alerts being published so that they can see the value of the information that is being published to Microsoft Teams. If there is no filtering that exists, the information has the potential to become “noisy” and when that happens, the value decreases.
Also, an operations team may want to perform different actions based upon the type of alert that has been created. As a result, we have created a switch statement within our logic app that allows us to treat alerts differently. For example, you may want to send some type of alerts to a desktop experience team if there is a virus, a networking team if there are IP address anomalies etc.
Building Logic App
There are currently no triggers available for the Microsoft Graph Security connector, so we will leverage a Recurrence trigger that will instantiate our logic app. For this scenario, we will set it to run every 2 hours, but you should set it to accommodate your needs.
Trigger
Next, we want to initialize a String variable called teamsMessage. We will use this variable as a common storage container for our message that we want publish to teams. This allows us to have a single Microsoft Teams connection and action.
Variable
We now want to retrieve any Microsoft Graph Security alerts for the past 2 hours by using the Microsoft Graph Security connector and the Get alerts action. As part of this call, we can include a Filter parameter which allows us to provide an OData query. Since we want to get alerts for the past 2 hours, our filter query will be createdDateTime gt addHours(utcNow(),-2).
Get Alerts
Note: The Microsoft Graph Security connector supports a variety of OData filters including
- $count
- $filter
- $orderby
- $select
- $skip
- $top
Using OData will allow us to address additional filtering needs that we may have including filtering on severity or alert type.
We will now include a check to see if there were any alerts being posted. We can do this using a Condition and use the length() expression to check to see if any alerts were returned from our Get Alerts call.
Condition
If we do not have any records, we will head down the If false (red) path. Within this condition, we will simply post a message indicating that we do not have any new alerts.
No New Alerts
When we do have alerts we will need to loop through each security alert using an Apply to each action. It is also important to enable Concurrency Control for this loop in its Settings experience and set it to 1. Using variables in a loop can create unpredictable results due to scaled-out processing. Setting concurrency to have a value of 1 (singleton) will cause the loop to take longer, but the data will be accurate and consistent. Refer to this #ServerlessTips by Turbo360 – Improve Performance of Azure Logic Apps using Parallelism
Within this loop, we will include a Switch statement where we will parse the different alerts and post to Microsoft Teams.
Alert Loop
Within my test tenant, I have been able to discover alerts with the following Alert Category:
- UnfamiliarLocation
- Malware
- UnwantedSoftware
- SuspiciousActivity
- General
- IpAnomaly
- SuspiciousSVCHOSTRareGroup
I suspect these alerts represent a small subset of the overall alerts that are captured.
Something to note about these different categories is that they will return a different message shapes (responses). This makes publishing a generic message to Microsoft Teams rather difficult as you will either keep it so generic that you have data that is not included in your message, or you start publishing attributes that are empty to teams which may raise data quality concerns.
To address this data consistency situation, I have gone through each of these different Alert Categor(ies) and created a Switch statement so that we can capture exactly the fields that we want to within our teamsMessage variable. As you can also see, there will be some subtle differences based upon the source of the alert. Capturing these details in a variable allows us to modify the message based upon our needs.
Note: It may be a good idea to just publish the alert messages to a data source where you can inspect the alerts to see which ones you want to prioritize and publish more specific details on to Microsoft Teams.
Switch Options
Naturally, a Switch statement will have a Default statement where we can capture any additional Alert Categor(ies) that weren’t available in our sample data. Should we find new events being made available, we can add an additional Switch statement later where we can target the specific information that we are interested in.
Our last step is to publish our message to Microsoft Teams. Within this action, we will use the teamsMessage variable as our Message as opposed to try and customize many different Microsoft Teams actions that account for our different types of alerts.
Teams
Testing
I had to play with my timeframe in order to capture an alert, but here is what it looks like when we have a SuspiciousActivity event.
When we do not have any alerts, we do see the following message. This gives security personnel an indication that automated monitoring is working. If this becomes too noisy, we can always not post anything when there are no new alerts.
Other Opportunities
The scenario we just walked through is a very simple example of how we can gain greater visibility into security events that are occurring within our organization. Once we have had an opportunity to better understand what events we now have coverage for, we can further optimize and automate even more of our operational tasks. In a recent blog post, Microsoft outlines a scenario where events can be assigned to an on-call resource and logged in ServiceNow, an IT Service Management tool. In addition, use approvals to close alerts back in the source system through this same connector. So not only can we gain insight, but we can now act on it.
Conclusion
The cybersecurity landscape continues to be a challenge for organizations. As a result, organizations may lean towards adding more headcount to protect themselves. While having more resources usually helps, it is important for those people to be used efficiently. Having people manually scan logs isn’t the greatest use of their time but having intelligent security systems in place that notify key resources when alerts are occurring creates efficiency opportunities.
Manually trying to detect ‘impossible login’ situations isn’t a great use of time, when a machine can detect this with more predictability. Also leveraging ‘wisdom of the crowd’ technologies allow you to gain learnings from other organizations who may have experienced a particular type of attack before it has a direct impact on your operations.
While ‘assuming breach’ is a reality that most organizations accept, it is important that organization play ‘offense’ and ‘defense’. Playing offense means deploying tools that protect your organization proactively and prevents, or reduces the likelihood of, a breach from occurring in the first place.
Leveraging intelligent cybersecurity tools allows you to redirect your resources to other valuable activities including developing cybersecurity playbooks, focusing on cybersecurity education and improving overall security hygiene. Using a flexible approach, like found in Azure Logic Apps, allows organizations to efficiently build-up defenses and quickly pivot when new threats emerge.