Automating security rocks! In a previous post I showed how to get started with Microsoft Defender ATP and Microsoft Flow: https://chrisonsecurity.net/2019/10/22/automate-mdatp-response-with-microsoft-flow/
Now, lets get a bit more into detail about automating security workflows. Unlike last time, I will use Azure Logic Apps instead of Flow. Both technologies are quite similar, however, they differ in licensing and some capabilities.
To find out more about Logic Apps you can take a look at these resources:
- https://azure.microsoft.com/en-us/services/logic-apps/
- https://docs.microsoft.com/en-us/azure/logic-apps/
One crucial aspect that has to be considered with automation is this: Is there a suitable connector that satisfies all needs for the work flow like the triggers you need or how you want to authenticate?
Default connectors
To get a variety of alerts at once, the Graph Security API connector is the obvious choice. It provides triggers for either all new alerts or new high severity alerts. Of course, you could also use the Defender ATP connector if you only need that subset of alerts.
Connectors always need credentials to authenticate against the service you want to access. This can become tricky, especially if you need to authenticate to different tenants or services. In case of the pre-built connectors a distinct connection must be established during the creation of the logic app:
As you can see above, the connection was done with a user account that has appropriate permissions. This is suitable for many simple workflows. Starting from there, you can wait for all kinds of alerts and start your actions.
HTTP REST calls
However, in more complex scenarios you might want to build you own API calls. Lets assume that during runtime it is uncertain which destination tenant will be called. So, we would have to put authentication information into the connector on-demand which is not possible with default connectors.
The good news is that all those connectors are based on different APIs, like the Microsoft Graph Security API or – in case of MDATP – the Securitycenter API. And there is a second advantage: we can now add additional security layers to the app, e.g. by using KeyVault to store secrets securely.
How can we access KeyVault secrets without entering credentials to the app? The answer is: managed identities. Those can be used to authenticate to Azure services in the app’s context without that necessity:
You only have to make sure that the application (that’s what the managed identity is in Azure AD) has the required permissions to access the KeyVault secret you specify in the logic app. “Get” and “List” are enough to access secrets in plain text:
We can then go ahead and use HTTP GET to query KeyVault:
The managed identity will take care of authentication by itself. If we parse the output using “Body” from the previous step of the HTTP GET we have direct access to the secret:
Parsing JSON needs a schema. You can use this one:
{
"type": "object",
"properties": {
"value": {
"type": "string"
},
"id": {
"type": "string"
}
}
}
The secret gets stored in the “value” property and can be used to access other endpoints as shown in the MDATP example below:
To get a comfortable editing experience you can then go ahead and parse that output again to have direct access to parameters like machine names, alert severity, etc.
Summing things up
As you might have noticed, this post was not intended to give detailed steps on how to build certain HTTP calls. However, what I wanted to show is that you are not dependent on default connectors while working with Azure Logic Apps. Using standards like HTTP REST offers increased flexibility to build more versatile workflows that can then also make use of other Azure services like KeyVault or Cosmos DB.
Thanks for reading!
Chris