A simple Logic App to export Sentinel incidents in Event Hub
Prologue
Recently I have been asked to support the set up of a side-by-side configuration between Sentinel and a 3rd party SIEM. In that scenario, Sentinel needed to send incidents and alerts to the 3rd party SIEM. The customer explicitly asked to have the correlation between incidents and related alerts on the Sentinel side: they didn't want to make that correlation on the target SIEM.
Sentinel offers two main approaches to replicate incidents to a third-party SIEM:
Log Analytics Data Export has the big advantage that it is an infrastructural configuration that can be set up with 1 click and that does not require the development and the deployment of any custom solutions. At the same time it has the disadvantage that it exports the target tables as they are, without any possibility to filter their content or to do some aggregation or transformation. Because of that, with this approach, the correlation of the Incidents and related alerts must be done on the target SIEM by matching the alert IDs available on each incident with the systemAlertId avaiable in each alert.
The following screenshot contains, as an example, the view, in Splunk, of a Sentinel incident exported to Event Hub through direct Log Analytics export of the SecurityIncident table. In order to retrieve incidents form Event Hub, in Splunk I added the add-on for Microsoft Cloud Services (Introduction - Splunk Add-on for Microsoft Cloud Services). Basically, the incident seen in Splunk is exactly the JSON representation of the incident row in the SecurityIncident table in Sentinel.?
In order to ensure that the target SIEM, for each incident, retrieves directly a JSON containing not only the properties of the incident but also all the details of the related alerts and even of the related entities, it is possible to create a custom Logic App. With this approach, at the price of a small custom development (but "low/no code"), it is also possible to apply the desired transformations
To automate the execution
In the following parts of this article I guide you through the creation of this Logic App starting from a template that includes a simple transformation on the JSON representation of the incident: the addition of a property with the URL of the incident in the new Unified Portal as described above.
Deploy the template
Get the JSON of the template from GitHub: sentinel-utilities/export-incident-to-event-hub at main · stefanpems/sentinel-utilities (github.com).
Notes about the JSON template for the Logic App:
1. The API Connection to Sentinel is configured to authenticate through the Managed Identity of the Logic App (the template contains "parameterValueType": "Alternative")
2. It was not possible to declare the use of the Managed Identity also for the API Connection to Event Hub (using the same declaration of "parameterValueType": "Alternative" returned an error of unsupported statement). Instead of setting the connection string to the API Connection created by the template, it is highly recommended to manually create a new API Connection to Event Hub using the Logic App's System Assigned Managed Identity. To do so, it is necessary to specify the URI of the Event Hub Namespace containing the target Event Hub. It is also necessary to assign the Event Hub "Send role" to that Managed Identity on the specified Event Hub. All these steps are described below.
Update Oct. 15, 2024 - The first three actions described below can be replaced by simply clicking the button "Deploy to Azure" added in the readme page.
In the Azure Portal, go to "Deploy a custom template" and select "Build your own template in the editor".
?Select "Load file" and select the JSON file of the template.?
?Click "Save".?
Select the desired Subscription. Select or create a Resource Group (it is recommended to create a dedicated Resource Group for this Logic App?
Select the desired region and specify a name for your Logic App. Write the name of the Event Hub to whom the Logic App should send the incidents (you can deploy the Logic App before the creation of the Event Hub; you can change the name of the Event Hub in the Logic App at any time). Click on "Review + create" and, then, "Create".?
The deployment terminates with the creation of 3 resources: 2 API Connections and 1 Logoc App template.?
Click on the name of the Logic App and, then, on the Edit button.?
You will be redirected on the editor. The initial "Error" message is related to the fact that the connection to Event Hub is not configured. Click on the "Send ModifiedIncident to EventHub" action and, then, on the link "Change connection" at the bottom of the right column.?
Here click on "Add new".
Note: instead of creating a new connection, you could use the existing connection and simply complete its configuration by specifying the "connection string" to the target Event Hub. You can do it by navigating back on the logic app page, out of the editor, and selecting "API Connection". It is recommended, though, to use Managed Identity instead of connection strings: that's why we describe how to proceed by adding a new connection using Managed Identity.?
Give a name to the new Connection (do not use the same name of the existing connection) and select "Logic Apps Managed Identity". Then specify the URI endpoint of the Event Hub Namespace hosting the target Event Hub and click "Create new"
Note: the endpoint of the Event Hub Namespace should have the format sb://<namespace>.servicebus.windows.net/
You can retrieve the FQDN of the Event Hub Namespace endpoint in the Azure Portal by navigating the Event Hub Namespace and selecting "Properties" (Attention: in the endpoint, the "https://" prefix must be replaced with "sb://", the port ":443" should not be specified and the last characted must be the "/"):?
Double check that you specify the endpoint in a format like this: sb://<FQDN>/?
When the new connection is created, the error on the Logic App disappears.?
Now it is possible to click on "Parameters" on the top button rows on the page. Here it is possible to verify and, if necessary, modify the name of the target Event Hub as specified while deploying the template.?
At the end of these configurations, do not forget to click on "Save".?
领英推荐
?
Now, exit the Logic App designer and click on Identity. Here it is possible to verify that the deployment of the Logic App has included the creation of a System Assigned Managed Identity
Note: on this same page the button "Azure role assignments" allows to assign the required "Azure Event Hub Data Sender" role to the Managed Identity at a subscription or resource group level. It is preferrable to assign this role on the specific target Event Hub as shown later.
?
Assign the role to the Logic App on Event Hub
In the Azure Portal, search for "Event Hubs", select the target Event Hub Namespace (the one whose endpoint was specified on the API connection of the Logic App) and, then, select the target Event Hub.?
Here open "Access control (IAM)" and assign the role? "Azure Event Hub Data Sender" role to the Managed Identity related to the just deplo "Azure Event Hub Data Sender" role to the Managed Identity at yed Logic App.?
Assign the visibility on the Logic App to Sentinel
In the Azure Portal, search for "Sentinel", open the desired workspace, select "Configuration" / "Settings" and then "Playbook permissions" / "Configure permissions".?
Here search for the the Resource Group containing the Logic App just created (the Resource Group that was specified while deploying the Logic App) and click "Apply".??
?
?
Testing the Logic App
In the Sentinel or in the Unified Portal, open the Incidents queue, select an incident and click on "Run playbook"
Select the new Logic App and click "Run".?
?
To check the result of the execution, go back on the Logic App, open History and check if the execution succeeded.?
You can also get the exact value of the JSON that was sent to Event Hub by opening that specific execution, selecting the action "Add property unifiedIncidentUrl to ModifiedIncident" and clicking on "Show raw outputs".??
Here is the (sanitized) JSON content copied from this field:
{
"body": {
"name": "ModifiedIncident",
"value": {
"id": "/subscriptions/<subscriptionID>/resourceGroups/sentinel-rg/providers/Microsoft.OperationalInsights/workspaces/sentinel/providers/Microsoft.SecurityInsights/Incidents/<ID>",
"name": "<ID>",
"etag": "\"d300<ID>\"",
"type": "Microsoft.SecurityInsights/Incidents",
"properties": {
"title": "Non Domain Controller Active Directory Replication on one endpoint",
"severity": "High",
"status": "New",
"owner": {
"objectId": null,
"email": null,
"assignedTo": null,
"userPrincipalName": null
},
"labels": [],
"firstActivityTimeUtc": "2024-10-09T11:34:09.3412106Z",
"lastActivityTimeUtc": "2024-10-10T18:17:58.5929505Z",
"lastModifiedTimeUtc": "2024-10-12T16:00:02.3906929Z",
"createdTimeUtc": "2024-10-11T15:53:36.7533333Z",
"incidentNumber": 117,
"additionalData": {
"alertsCount": 2,
"bookmarksCount": 0,
"commentsCount": 0,
"alertProductNames": [
"Azure Sentinel"
],
"tactics": [
"CredentialAccess"
],
"techniques": [
"T1003"
]
},
"relatedAnalyticRuleIds": [
"/subscriptions/<subscriptionID>/resourceGroups/sentinel-rg/providers/Microsoft.OperationalInsights/workspaces/sentinel/providers/Microsoft.SecurityInsights/alertRules/<ID>"
],
"incidentUrl": "https://portal.azure.com/#asset/Microsoft_Azure_Security_Insights/Incident/subscriptions/<subscriptionID>/resourceGroups/sentinel-rg/providers/Microsoft.OperationalInsights/workspaces/sentinel/providers/Microsoft.SecurityInsights/Incidents/<ID>",
"providerName": "Microsoft XDR",
"providerIncidentId": "265",
"alerts": [
{
"id": "/subscriptions/<subscriptionID>/resourceGroups/sentinel-rg/providers/Microsoft.OperationalInsights/workspaces/sentinel/providers/Microsoft.SecurityInsights/Entities/<ID>",
"name": "<ID>",
"type": "Microsoft.SecurityInsights/Entities",
"kind": "SecurityAlert",
"properties": {
"systemAlertId": "<ID>",
"tactics": [
"CredentialAccess"
],
"alertDisplayName": "Non Domain Controller Active Directory Replication",
"description": "This query detects potential attempts by non-computer accounts (non domain controllers) to retrieve/synchronize an active directory object leveraging directory replication services (DRS).\nA Domain Controller (computer account) would usually be performing these actions in a domain environment. Another detection rule can be created to cover domain controllers accounts doing at rare times.\nA domain user with privileged permissions to use directory replication services is rare.",
"confidenceLevel": "Unknown",
"severity": "High",
"vendorName": "Microsoft",
"productName": "Azure Sentinel",
"productComponentName": "Scheduled Alerts",
"alertType": "<ID>_<ID>",
"processingEndTime": "2024-10-11T15:53:24.953131Z",
"status": "New",
"endTimeUtc": "2024-10-10T18:17:58.5929505Z",
"startTimeUtc": "2024-10-09T11:34:09.3412106Z",
"timeGenerated": "2024-10-11T15:53:25.0006613Z",
"providerAlertId": "<ID>",
"resourceIdentifiers": [
{
"type": "LogAnalytics",
"workspaceId": "<ID>"
}
],
"additionalData": {
"ProcessedBySentinel": "True",
"Alert generation status": "Full alert created",
"Query Period": "7.00:00:00",
"Trigger Operator": "GreaterThan",
"Trigger Threshold": "0",
"Correlation Id": "<ID>",
"Search Query Results Overall Count": "2391",
"Data Sources": "[\"sentinel\"]",
"Query": "https:// The query_now parameter represents the time (in UTC) at which the scheduled analytics rule ran to produce this alert.\nset query_now = datetime(2024-10-11T15:48:23.8393213Z);\n// Enter a reference list of hostnames for your DC servers\n//...",
"Query Start Time UTC": "2024-10-04T15:48:23Z",
"Query End Time UTC": "2024-10-11T15:48:24Z",
"Analytic Rule Ids": "[\"<ID>\"]",
"Event Grouping": "SingleAlert",
"Analytic Rule Name": "Non Domain Controller Active Directory Replication",
"Analytics Template Id": "<ID>"
},
"friendlyName": "Non Domain Controller Active Directory Replication"
}
},
{
"id": "/subscriptions/<subscriptionID>/resourceGroups/sentinel-rg/providers/Microsoft.OperationalInsights/workspaces/sentinel/providers/Microsoft.SecurityInsights/Entities/<ID>",
"name": "<ID>",
"type": "Microsoft.SecurityInsights/Entities",
"kind": "SecurityAlert",
"properties": {
"systemAlertId": "<ID>",
"tactics": [
"CredentialAccess"
],
"alertDisplayName": "Non Domain Controller Active Directory Replication",
"description": "This query detects potential attempts by non-computer accounts (non domain controllers) to retrieve/synchronize an active directory object leveraging directory replication services (DRS).\nA Domain Controller (computer account) would usually be performing these actions in a domain environment. Another detection rule can be created to cover domain controllers accounts doing at rare times.\nA domain user with privileged permissions to use directory replication services is rare.",
"confidenceLevel": "Unknown",
"severity": "High",
"vendorName": "Microsoft",
"productName": "Azure Sentinel",
"productComponentName": "Scheduled Alerts",
"alertType": "<ID>_<ID>",
"processingEndTime": "2024-10-12T15:53:25.9680356Z",
"status": "New",
"endTimeUtc": "2024-10-10T18:17:58.5929505Z",
"startTimeUtc": "2024-10-09T11:34:09.3412106Z",
"timeGenerated": "2024-10-12T15:53:25.9894266Z",
"providerAlertId": "<ID>",
"resourceIdentifiers": [
{
"type": "LogAnalytics",
"workspaceId": "<ID>"
}
],
"additionalData": {
"ProcessedBySentinel": "True",
"Alert generation status": "Full alert created",
"Query Period": "7.00:00:00",
"Trigger Operator": "GreaterThan",
"Trigger Threshold": "0",
"Correlation Id": "<ID>",
"Analytics Template Id": "<ID>",
"Search Query Results Overall Count": "2391",
"Data Sources": "[\"sentinel\"]",
"Query": "https:// The query_now parameter represents the time (in UTC) at which the scheduled analytics rule ran to produce this alert.\nset query_now = datetime(2024-10-12T15:48:23.8393213Z);\n// Enter a reference list of hostnames for your DC servers\n/...",
"Query Start Time UTC": "2024-10-05T15:48:23Z",
"Query End Time UTC": "2024-10-12T15:48:24Z",
"Analytic Rule Ids": "[\"<ID>\"]",
"Event Grouping": "SingleAlert",
"Analytic Rule Name": "Non Domain Controller Active Directory Replication"
},
"friendlyName": "Non Domain Controller Active Directory Replication"
}
}
],
"bookmarks": [],
"relatedEntities": [
{
"id": "/subscriptions/<subscriptionID>/resourceGroups/sentinel-rg/providers/Microsoft.OperationalInsights/workspaces/sentinel/providers/Microsoft.SecurityInsights/Entities/<ID>",
"name": "<ID>",
"type": "Microsoft.SecurityInsights/Entities",
"kind": "Account",
"properties": {
"accountName": "MSOL_<ID>",
"ntDomain": "Contoso",
"isDomainJoined": true,
"displayName": "Contoso\\MSOL_<ID>",
"friendlyName": "Contoso\\MSOL_<ID>"
}
},
{
"id": "/subscriptions/<subscriptionID>/resourceGroups/sentinel-rg/providers/Microsoft.OperationalInsights/workspaces/sentinel/providers/Microsoft.SecurityInsights/Entities/<ID>",
"name": "<ID>",
"type": "Microsoft.SecurityInsights/Entities",
"kind": "Host",
"properties": {
"dnsDomain": "contoso.local",
"ntDomain": "contoso.local",
"hostName": "contosodc1",
"netBiosName": "contosodc1.contoso.local",
"azureID": "/subscriptions/<subscriptionID>/resourcegroups/arc1-rg/providers/microsoft.hybridcompute/machines/contosodc1",
"omsAgentID": "<ID>",
"osFamily": "Windows",
"osVersion": "Windows",
"additionalData": {
"ResourceId": "/subscriptions/<subscriptionID>/resourceGroups/arc1-rg/providers/Microsoft.HybridCompute/machines/contosodc1",
"VMUUID": "<ID>",
"SubscriptionId": "<ID>"
},
"friendlyName": "contosodc1"
}
}
],
"comments": []
},
"unifiedIncidentUrl": "https://security.microsoft.com/incident2/265/overview"
}
}
}
This content is sent as a base64 string to Event Hub.?
On the performance counters of the Event Hub it is possible to see if the messages sent by the Logic App are correctly arriving.?
?
As an example, here is the view of the JSON representation of that incident as read by Splunk from the Event Hub. At the bottom of the JSON it is possible to read the URL of the incident in the new Unified Portal as added by the Logic App.?
It is also possible to notice that the JSON contains the alerts and the entities related to the incident (basically, all the details that is possible to read into the incident page on Sentinel). ?
Specifically, the JSON received by the 3rd party SIEM contains, together with the properties of the incident, also all the relevant details of the alerts and of the related entities.
If you want even more details - for example, if you want to add to the JSON also the "events" related to each alert, which means the results of the specific analytic rule that triggered each alert - you can follow the approach documented here: Sending enriched Microsoft Sentinel alerts to 3rd party SIEM and Ticketing Systems - Microsoft Community Hub (the article references a template in GitHub). In many cases, sending to the 3rd party SIEM the huge amount of additional details contained in each "event" is not really needed: most of the time, the security analysts working on that external SIEM prefer to follow the link of the received incident in order to open and investatigate it directly in the originating portal: the Microsoft Sentinel blade in the Azure portal or, now, the Defender portal extended as new Unified SOC portal.
I hope that the Logic App template shared in this article and the entire explanation written above will be useful to you in quickly and effectively implementing the desired configuration of Microsoft Sentinel in a side-by-side configuration with another SIEM.