Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
{
"name": "AbnormalSecurityPushDCR",
"apiVersion": "2021-09-01-preview",
"type": "Microsoft.Insights/dataCollectionRules",
"location": "[parameters('workspace-location')]",
"properties": {
"dataCollectionEndpointId": "[resourceId(parameters('subscription'), parameters('resourceGroupName'), 'Microsoft.Insights/dataCollectionEndpoints', parameters('workspace'))]",
"streamDeclarations": {
"Custom-AbnormalSecurityLogs": {
"columns": [
{ "name": "Time", "type": "string" },
{ "name": "abx_body", "type": "dynamic" },
{ "name": "abx_metadata", "type": "dynamic" }
]
},
"Custom-ABNORMAL_SECURITY_THREAT_LOG": {
"columns": [
{ "name": "Time", "type": "string" },
{ "name": "abx_body", "type": "dynamic" },
{ "name": "abx_metadata", "type": "dynamic" }
]
},
"Custom-ABNORMAL_SECURITY_CASE": {
"columns": [
{ "name": "Time", "type": "string" },
{ "name": "abx_body", "type": "dynamic" },
{ "name": "abx_metadata", "type": "dynamic" }
]
},
"Custom-ABNORMAL_SECURITY_AUDIT_LOG": {
"columns": [
{ "name": "Time", "type": "string" },
{ "name": "abx_body", "type": "dynamic" },
{ "name": "abx_metadata", "type": "dynamic" }
]
},
"Custom-ABNORMAL_SECURITY_ABUSE_MAILBOX": {
"columns": [
{ "name": "Time", "type": "string" },
{ "name": "abx_body", "type": "dynamic" },
{ "name": "abx_metadata", "type": "dynamic" }
]
},
"Custom-ABNORMAL_SECURITY_POSTURE_CHANGE": {
"columns": [
{ "name": "Time", "type": "string" },
{ "name": "abx_body", "type": "dynamic" },
{ "name": "abx_metadata", "type": "dynamic" }
]
},
"Custom-ABNORMAL_SECURITY_ATO_CASE": {
"columns": [
{ "name": "Time", "type": "string" },
{ "name": "abx_body", "type": "dynamic" },
{ "name": "abx_metadata", "type": "dynamic" }
]
},
"Custom-ABNORMAL_SECURITY_REMEDIATION": {
"columns": [
{ "name": "Time", "type": "string" },
{ "name": "abx_body", "type": "dynamic" },
{ "name": "abx_metadata", "type": "dynamic" }
]
},
"Custom-ABNORMAL_SECURITY_VENDOR_CASE": {
"columns": [
{ "name": "Time", "type": "string" },
{ "name": "abx_body", "type": "dynamic" },
{ "name": "abx_metadata", "type": "dynamic" }
]
}
},
"destinations": {
"logAnalytics": [
{
"workspaceResourceId": "[variables('workspaceResourceId')]",
"name": "clv2ws1"
}
]
},
"dataFlows": [
{
"streams": ["Custom-AbnormalSecurityLogs"],
"destinations": ["clv2ws1"],
"transformKql": "source | extend TimeGenerated = todatetime(Time)",
"outputStream": "Custom-AbnormalSecurityLogs_CL"
},
{
"streams": ["Custom-ABNORMAL_SECURITY_THREAT_LOG"],
"destinations": ["clv2ws1"],
"transformKql": "source | extend TimeGenerated = todatetime(Time)",
"outputStream": "Custom-ABNORMAL_SECURITY_THREAT_LOG_CL"
},
{
"streams": ["Custom-ABNORMAL_SECURITY_CASE"],
"destinations": ["clv2ws1"],
"transformKql": "source | extend TimeGenerated = todatetime(Time)",
"outputStream": "Custom-ABNORMAL_SECURITY_CASE_CL"
},
{
"streams": ["Custom-ABNORMAL_SECURITY_AUDIT_LOG"],
"destinations": ["clv2ws1"],
"transformKql": "source | extend TimeGenerated = todatetime(Time)",
"outputStream": "Custom-ABNORMAL_SECURITY_AUDIT_LOG_CL"
},
{
"streams": ["Custom-ABNORMAL_SECURITY_ABUSE_MAILBOX"],
"destinations": ["clv2ws1"],
"transformKql": "source | extend TimeGenerated = todatetime(Time)",
"outputStream": "Custom-ABNORMAL_SECURITY_ABUSE_MAILBOX_CL"
},
{
"streams": ["Custom-ABNORMAL_SECURITY_POSTURE_CHANGE"],
"destinations": ["clv2ws1"],
"transformKql": "source | extend TimeGenerated = todatetime(Time)",
"outputStream": "Custom-ABNORMAL_SECURITY_POSTURE_CHANGE_CL"
},
{
"streams": ["Custom-ABNORMAL_SECURITY_ATO_CASE"],
"destinations": ["clv2ws1"],
"transformKql": "source | extend TimeGenerated = todatetime(Time)",
"outputStream": "Custom-ABNORMAL_SECURITY_ATO_CASE_CL"
},
{
"streams": ["Custom-ABNORMAL_SECURITY_REMEDIATION"],
"destinations": ["clv2ws1"],
"transformKql": "source | extend TimeGenerated = todatetime(Time)",
"outputStream": "Custom-ABNORMAL_SECURITY_REMEDIATION_CL"
},
{
"streams": ["Custom-ABNORMAL_SECURITY_VENDOR_CASE"],
"destinations": ["clv2ws1"],
"transformKql": "source | extend TimeGenerated = todatetime(Time)",
"outputStream": "Custom-ABNORMAL_SECURITY_VENDOR_CASE_CL"
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
{
"name": "AbnormalSecurityPush",
"apiVersion": "2022-09-01-preview",
"type": "Microsoft.SecurityInsights/dataConnectorDefinitions",
"location": "[parameters('workspace-location')]",
"kind": "Customizable",
"properties": {
"connectorUiConfig": {
"id": "AbnormalSecurityPush",
"title": "Abnormal Security (Push)",
"publisher": "Abnormal Security",
"descriptionMarkdown": "The [Abnormal Security](https://abnormalsecurity.com) connector pushes real-time security events (threats, cases, audit logs, abuse mailbox reports, posture changes, ATO cases, remediations, and vendor cases) from Abnormal's cloud email security platform into Microsoft Sentinel using the Codeless Connector Framework (CCF) Push pattern. Events are routed to per-event-type tables matching the legacy connector naming convention, enabling seamless migration.",
"graphQueries": [
{
"metricName": "Threat Logs",
"legend": "ABNORMAL_SECURITY_THREAT_LOG_CL",
"baseQuery": "ABNORMAL_SECURITY_THREAT_LOG_CL"
},
{
"metricName": "Cases",
"legend": "ABNORMAL_SECURITY_CASE_CL",
"baseQuery": "ABNORMAL_SECURITY_CASE_CL"
},
{
"metricName": "Audit Logs",
"legend": "ABNORMAL_SECURITY_AUDIT_LOG_CL",
"baseQuery": "ABNORMAL_SECURITY_AUDIT_LOG_CL"
},
{
"metricName": "Abuse Mailbox",
"legend": "ABNORMAL_SECURITY_ABUSE_MAILBOX_CL",
"baseQuery": "ABNORMAL_SECURITY_ABUSE_MAILBOX_CL"
},
{
"metricName": "Posture Changes",
"legend": "ABNORMAL_SECURITY_POSTURE_CHANGE_CL",
"baseQuery": "ABNORMAL_SECURITY_POSTURE_CHANGE_CL"
},
{
"metricName": "ATO Cases",
"legend": "ABNORMAL_SECURITY_ATO_CASE_CL",
"baseQuery": "ABNORMAL_SECURITY_ATO_CASE_CL"
},
{
"metricName": "Remediations",
"legend": "ABNORMAL_SECURITY_REMEDIATION_CL",
"baseQuery": "ABNORMAL_SECURITY_REMEDIATION_CL"
},
{
"metricName": "Vendor Cases",
"legend": "ABNORMAL_SECURITY_VENDOR_CASE_CL",
"baseQuery": "ABNORMAL_SECURITY_VENDOR_CASE_CL"
},
{
"metricName": "Other Events (Fallback)",
"legend": "AbnormalSecurityLogs_CL",
"baseQuery": "AbnormalSecurityLogs_CL"
}
],
"sampleQueries": [
{
"description": "All Abnormal Security events across all tables",
"query": "union ABNORMAL_SECURITY_THREAT_LOG_CL, ABNORMAL_SECURITY_CASE_CL, ABNORMAL_SECURITY_AUDIT_LOG_CL, ABNORMAL_SECURITY_ABUSE_MAILBOX_CL, ABNORMAL_SECURITY_POSTURE_CHANGE_CL, ABNORMAL_SECURITY_ATO_CASE_CL, ABNORMAL_SECURITY_REMEDIATION_CL, ABNORMAL_SECURITY_VENDOR_CASE_CL, AbnormalSecurityLogs_CL\n | sort by TimeGenerated desc\n | take 100"
},
{
"description": "Threat logs by severity",
"query": "ABNORMAL_SECURITY_THREAT_LOG_CL\n | extend severity = tostring(abx_body.severity)\n | summarize count() by severity\n | sort by count_ desc"
},
{
"description": "Cases by status (last 7 days)",
"query": "ABNORMAL_SECURITY_CASE_CL\n | where TimeGenerated > ago(7d)\n | extend status = tostring(abx_body.status)\n | summarize count() by status\n | sort by count_ desc"
},
{
"description": "Event volume by type (last 24h)",
"query": "union ABNORMAL_SECURITY_THREAT_LOG_CL, ABNORMAL_SECURITY_CASE_CL, ABNORMAL_SECURITY_AUDIT_LOG_CL, ABNORMAL_SECURITY_ABUSE_MAILBOX_CL, ABNORMAL_SECURITY_POSTURE_CHANGE_CL, ABNORMAL_SECURITY_ATO_CASE_CL, ABNORMAL_SECURITY_REMEDIATION_CL, ABNORMAL_SECURITY_VENDOR_CASE_CL, AbnormalSecurityLogs_CL\n | where TimeGenerated > ago(24h)\n | extend event_type = tostring(abx_metadata.event_type)\n | summarize count() by event_type\n | order by count_ desc"
}
],
"dataTypes": [
{ "name": "ABNORMAL_SECURITY_THREAT_LOG_CL", "lastDataReceivedQuery": "ABNORMAL_SECURITY_THREAT_LOG_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" },
{ "name": "ABNORMAL_SECURITY_CASE_CL", "lastDataReceivedQuery": "ABNORMAL_SECURITY_CASE_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" },
{ "name": "ABNORMAL_SECURITY_AUDIT_LOG_CL", "lastDataReceivedQuery": "ABNORMAL_SECURITY_AUDIT_LOG_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" },
{ "name": "ABNORMAL_SECURITY_ABUSE_MAILBOX_CL", "lastDataReceivedQuery": "ABNORMAL_SECURITY_ABUSE_MAILBOX_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" },
{ "name": "ABNORMAL_SECURITY_POSTURE_CHANGE_CL", "lastDataReceivedQuery": "ABNORMAL_SECURITY_POSTURE_CHANGE_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" },
{ "name": "ABNORMAL_SECURITY_ATO_CASE_CL", "lastDataReceivedQuery": "ABNORMAL_SECURITY_ATO_CASE_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" },
{ "name": "ABNORMAL_SECURITY_REMEDIATION_CL", "lastDataReceivedQuery": "ABNORMAL_SECURITY_REMEDIATION_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" },
{ "name": "ABNORMAL_SECURITY_VENDOR_CASE_CL", "lastDataReceivedQuery": "ABNORMAL_SECURITY_VENDOR_CASE_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" },
{ "name": "AbnormalSecurityLogs_CL", "lastDataReceivedQuery": "AbnormalSecurityLogs_CL\n| summarize Time = max(TimeGenerated)\n| where isnotempty(Time)" }
],
"connectivityCriteria": [
{
"type": "IsConnectedQuery",
"value": [
"union ABNORMAL_SECURITY_THREAT_LOG_CL, ABNORMAL_SECURITY_CASE_CL, ABNORMAL_SECURITY_AUDIT_LOG_CL, ABNORMAL_SECURITY_ABUSE_MAILBOX_CL, ABNORMAL_SECURITY_POSTURE_CHANGE_CL, ABNORMAL_SECURITY_ATO_CASE_CL, ABNORMAL_SECURITY_REMEDIATION_CL, ABNORMAL_SECURITY_VENDOR_CASE_CL, AbnormalSecurityLogs_CL\n| summarize LastLogReceived = max(TimeGenerated)\n| project IsConnected = LastLogReceived > ago(7d)"
]
}
],
"availability": {
"status": 1
},
"permissions": {
"resourceProvider": [
{
"provider": "Microsoft.OperationalInsights/workspaces",
"permissionsDisplayText": "read and write permissions are required.",
"providerDisplayName": "Workspace",
"scope": "Workspace",
"requiredPermissions": {
"write": true,
"read": true,
"delete": true
}
}
],
"customs": [
{
"name": "Microsoft Entra",
"description": "Permission to create an app registration in Microsoft Entra ID. Typically requires Entra ID Application Developer role or higher."
},
{
"name": "Microsoft Azure",
"description": "Permission to assign Monitoring Metrics Publisher role on data collection rule (DCR). Typically requires Azure RBAC Owner or User Access Administrator role."
},
{
"name": "Abnormal Security",
"description": "Active Abnormal Security subscription with access to the SIEM integration settings."
}
]
},
"instructionSteps": [
{
"title": "1. Deploy Connector Resources",
"description": "This connector enables Abnormal Security to push real-time security events directly to Microsoft Sentinel via the Azure Monitor Ingestion API.",
"instructions": [
{
"type": "Markdown",
"parameters": {
"content": "#### Automated Configuration\nClicking **Deploy** will create:\n- 9 custom log tables for per-event-type routing\n- Data Collection Rule (DCR) with 9 streams\n- Data Collection Endpoint (DCE) for ingestion\n- Microsoft Entra application with OAuth credentials\n- Required IAM role assignments (Monitoring Metrics Publisher)\n\nThis enables Abnormal Security to securely push events using OAuth 2.0 client credentials."
}
},
{
"type": "DeployPushConnectorButton",
"parameters": {
"label": "Deploy Abnormal Security Push Connector",
"applicationDisplayName": "Abnormal Security Sentinel Push Connector"
}
}
]
},
{
"title": "2. Configure Abnormal Security",
"description": "Use the following parameters to configure the Microsoft Sentinel integration in the Abnormal Security Portal.",
"instructions": [
{
"type": "CopyableLabel",
"parameters": {
"label": "Tenant ID (Directory ID)",
"fillWith": ["TenantId"]
}
},
{
"type": "CopyableLabel",
"parameters": {
"label": "Application (Client) ID",
"fillWith": ["ApplicationId"],
"placeholder": "Deploy push connector to get the Application ID"
}
},
{
"type": "CopyableLabel",
"parameters": {
"label": "Client Secret",
"fillWith": ["ApplicationSecret"],
"placeholder": "Deploy push connector to get the Client Secret"
}
},
{
"type": "CopyableLabel",
"parameters": {
"label": "Data Collection Endpoint URI",
"fillWith": ["DataCollectionEndpoint"],
"placeholder": "Deploy push connector to get the DCE Endpoint"
}
},
{
"type": "CopyableLabel",
"parameters": {
"label": "Data Collection Rule Immutable ID",
"fillWith": ["DataCollectionRuleId"],
"placeholder": "Deploy push connector to get the DCR Immutable ID"
}
},
{
"type": "CopyableLabel",
"parameters": {
"label": "Fallback Stream Name",
"value": "Custom-AbnormalSecurityLogs"
}
},
{
"type": "CopyableLabel",
"parameters": {
"label": "Stream Prefix (for per-event-type routing)",
"value": "Custom-ABNORMAL_SECURITY_"
}
},
{
"type": "Markdown",
"parameters": {
"content": "#### Configure in Abnormal Security Portal\n1. Log in to [Abnormal Security Portal](https://portal.abnormalsecurity.com)\n2. Navigate to **Settings > Integrations > SIEM**\n3. Select **Microsoft Sentinel (Azure Monitor CCF)**\n4. Enter all 7 values from above\n5. Click **Verify Credentials** to test the connection\n6. Click **Save** and **Enable** the integration\n\n**Multi-table routing:** Events are automatically routed to per-event-type tables (e.g., threat logs → `ABNORMAL_SECURITY_THREAT_LOG_CL`, cases → `ABNORMAL_SECURITY_CASE_CL`). Unknown event types go to the fallback table `AbnormalSecurityLogs_CL`."
}
}
]
},
{
"title": "3. Verify Data Ingestion",
"description": "Confirm events are flowing from Abnormal Security to Sentinel.",
"instructions": [
{
"type": "Markdown",
"parameters": {
"content": "Wait 5-10 minutes after enabling the integration, then run this KQL query:\n\nunion ABNORMAL_SECURITY_THREAT_LOG_CL, ABNORMAL_SECURITY_CASE_CL, ABNORMAL_SECURITY_AUDIT_LOG_CL, ABNORMAL_SECURITY_ABUSE_MAILBOX_CL, ABNORMAL_SECURITY_POSTURE_CHANGE_CL, ABNORMAL_SECURITY_ATO_CASE_CL, ABNORMAL_SECURITY_REMEDIATION_CL, ABNORMAL_SECURITY_VENDOR_CASE_CL, AbnormalSecurityLogs_CL | where TimeGenerated > ago(1h) | extend event_type = tostring(abx_metadata.event_type) | summarize count() by event_type | order by count_ desc\n\nIf no data appears after 15 minutes, verify credentials in the Abnormal Security Portal and check Azure Monitor for ingestion errors."
}
}
]
}
]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "AbnormalSecurityPushConnector",
"apiVersion": "2024-09-01",
"type": "Microsoft.SecurityInsights/dataConnectors",
"kind": "Push",
"properties": {
"connectorDefinitionName": "AbnormalSecurityPush",
"dcrConfig": {
"streamName": "Custom-AbnormalSecurityLogs",
"dataCollectionEndpoint": "[[parameters('dcrConfig').dataCollectionEndpoint]",
"dataCollectionRuleImmutableId": "[[parameters('dcrConfig').dataCollectionRuleImmutableId]"
},
"auth": {
"type": "Push",
"AppId": "[[parameters('auth').appId]",
"ServicePrincipalId": "[[parameters('auth').servicePrincipalId]"
},
"request": {
"RetryCount": 1
},
"response": {
"eventsJsonPaths": ["$"]
}
}
}
Loading
Loading