Analytic rule catalog
Dataverse - Suspicious use of TDS endpoint
Back
| Id | d875af10-6bb9-4d6a-a6e4-78439a98bf4b |
| Rulename | Dataverse - Suspicious use of TDS endpoint |
| Description | Identifies Dataverse TDS (Tabular Data Stream) protocol based queries where the source user or IP address has recent security alerts and the TDS protocol has not been used previously in the target environment. |
| Severity | Low |
| Tactics | Exfiltration InitialAccess |
| Techniques | T1048 T1190 |
| Required data connectors | AzureActiveDirectoryIdentityProtection Dataverse |
| Kind | Scheduled |
| Query frequency | 1h |
| Query period | 14d |
| Trigger threshold | 0 |
| Trigger operator | gt |
| Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft%20Business%20Applications/Analytic%20Rules/Dataverse%20-%20Suspicious%20use%20of%20TDS%20endpoint.yaml |
| Version | 3.2.0 |
| Arm template | d875af10-6bb9-4d6a-a6e4-78439a98bf4b.json |
let query_frequency = 1h;
let query_lookback = 14d;
DataverseActivity
| where TimeGenerated >= ago(query_frequency)
| where Message == 'ExecutePowerBISql'
| summarize FirstEvent = min(TimeGenerated) by UserId, ClientIp, InstanceUrl
| join kind=inner(
DataverseActivity
| where TimeGenerated >= ago(query_lookback)
| where Message == 'ExecutePowerBISql'
| summarize UniqueUsers = dcount(UserId, 4) by InstanceUrl)
on InstanceUrl
| where UniqueUsers == 1
| join kind=inner (
SecurityAlert
| where Entities has ('"Type":"ip"')
| project AlertName, SystemAlertId, Entities
| mv-expand todynamic(Entities)
| where Entities.Type == "ip"
| extend IPAddress = tostring(Entities.Address)
| summarize SystemAlerts = make_set(SystemAlertId, 100), Alerts = make_set(AlertName, 100) by IPAddress)
on $left.ClientIp == $right.IPAddress
| extend
CloudAppId = int(32780),
AccountName = tostring(split(UserId, '@')[0]),
UPNSuffix = tostring(split(UserId, '@')[1])
| join kind = inner (
SecurityAlert
| where Entities has ('Type":"account"')
| project AlertName, SystemAlertId, Entities
| mv-expand todynamic(Entities)
| where Entities.Type == "account"
| extend
UPNSuffix = tostring(Entities.UPNSuffix),
AccountName = tostring(Entities.Name)
| summarize SystemAlerts = make_set(SystemAlertId, 100), Alerts = make_set(AlertName, 100) by AccountName, UPNSuffix
| where isnotempty(AccountName) and isnotempty(UPNSuffix))
on AccountName, UPNSuffix
| summarize SystemAlerts = make_set(SystemAlerts, 100), Alerts = make_set(Alerts, 100) by FirstEvent, UserId, ClientIp, InstanceUrl, AccountName, UPNSuffix
| extend CloudAppId = int(32780)
| project
FirstEvent,
UserId,
ClientIp,
InstanceUrl,
Alerts,
SystemAlerts,
CloudAppId,
AccountName,
UPNSuffix
query: |
let query_frequency = 1h;
let query_lookback = 14d;
DataverseActivity
| where TimeGenerated >= ago(query_frequency)
| where Message == 'ExecutePowerBISql'
| summarize FirstEvent = min(TimeGenerated) by UserId, ClientIp, InstanceUrl
| join kind=inner(
DataverseActivity
| where TimeGenerated >= ago(query_lookback)
| where Message == 'ExecutePowerBISql'
| summarize UniqueUsers = dcount(UserId, 4) by InstanceUrl)
on InstanceUrl
| where UniqueUsers == 1
| join kind=inner (
SecurityAlert
| where Entities has ('"Type":"ip"')
| project AlertName, SystemAlertId, Entities
| mv-expand todynamic(Entities)
| where Entities.Type == "ip"
| extend IPAddress = tostring(Entities.Address)
| summarize SystemAlerts = make_set(SystemAlertId, 100), Alerts = make_set(AlertName, 100) by IPAddress)
on $left.ClientIp == $right.IPAddress
| extend
CloudAppId = int(32780),
AccountName = tostring(split(UserId, '@')[0]),
UPNSuffix = tostring(split(UserId, '@')[1])
| join kind = inner (
SecurityAlert
| where Entities has ('Type":"account"')
| project AlertName, SystemAlertId, Entities
| mv-expand todynamic(Entities)
| where Entities.Type == "account"
| extend
UPNSuffix = tostring(Entities.UPNSuffix),
AccountName = tostring(Entities.Name)
| summarize SystemAlerts = make_set(SystemAlertId, 100), Alerts = make_set(AlertName, 100) by AccountName, UPNSuffix
| where isnotempty(AccountName) and isnotempty(UPNSuffix))
on AccountName, UPNSuffix
| summarize SystemAlerts = make_set(SystemAlerts, 100), Alerts = make_set(Alerts, 100) by FirstEvent, UserId, ClientIp, InstanceUrl, AccountName, UPNSuffix
| extend CloudAppId = int(32780)
| project
FirstEvent,
UserId,
ClientIp,
InstanceUrl,
Alerts,
SystemAlerts,
CloudAppId,
AccountName,
UPNSuffix
status: Available
id: d875af10-6bb9-4d6a-a6e4-78439a98bf4b
tactics:
- Exfiltration
- InitialAccess
version: 3.2.0
triggerOperator: gt
entityMappings:
- fieldMappings:
- columnName: AccountName
identifier: Name
- columnName: UPNSuffix
identifier: UPNSuffix
entityType: Account
- fieldMappings:
- columnName: CloudAppId
identifier: AppId
- columnName: InstanceUrl
identifier: InstanceName
entityType: CloudApplication
- fieldMappings:
- columnName: ClientIp
identifier: Address
entityType: IP
alertDetailsOverride:
alertDisplayNameFormat: 'Dataverse - Suspicious use of TDS endpoint in {{InstanceUrl}} '
alertDescriptionFormat: 'The TDS endpoint was used to query Dataverse instance {{InstanceUrl}} . The use of this protocol was not seen previously and the following alerts were associated with the caller: {{Alerts}}'
severity: Low
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft%20Business%20Applications/Analytic%20Rules/Dataverse%20-%20Suspicious%20use%20of%20TDS%20endpoint.yaml
kind: Scheduled
requiredDataConnectors:
- connectorId: Dataverse
dataTypes:
- DataverseActivity
- connectorId: AzureActiveDirectoryIdentityProtection
dataTypes:
- SecurityAlert
queryFrequency: 1h
triggerThreshold: 0
queryPeriod: 14d
description: Identifies Dataverse TDS (Tabular Data Stream) protocol based queries where the source user or IP address has recent security alerts and the TDS protocol has not been used previously in the target environment.
name: Dataverse - Suspicious use of TDS endpoint
relevantTechniques:
- T1048
- T1190
eventGroupingSettings:
aggregationKind: AlertPerResult
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspace": {
"type": "String"
}
},
"resources": [
{
"apiVersion": "2024-01-01-preview",
"id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/d875af10-6bb9-4d6a-a6e4-78439a98bf4b')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/d875af10-6bb9-4d6a-a6e4-78439a98bf4b')]",
"properties": {
"alertDetailsOverride": {
"alertDescriptionFormat": "The TDS endpoint was used to query Dataverse instance {{InstanceUrl}} . The use of this protocol was not seen previously and the following alerts were associated with the caller: {{Alerts}}",
"alertDisplayNameFormat": "Dataverse - Suspicious use of TDS endpoint in {{InstanceUrl}} "
},
"alertRuleTemplateName": "d875af10-6bb9-4d6a-a6e4-78439a98bf4b",
"customDetails": null,
"description": "Identifies Dataverse TDS (Tabular Data Stream) protocol based queries where the source user or IP address has recent security alerts and the TDS protocol has not been used previously in the target environment.",
"displayName": "Dataverse - Suspicious use of TDS endpoint",
"enabled": true,
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "AccountName",
"identifier": "Name"
},
{
"columnName": "UPNSuffix",
"identifier": "UPNSuffix"
}
]
},
{
"entityType": "CloudApplication",
"fieldMappings": [
{
"columnName": "CloudAppId",
"identifier": "AppId"
},
{
"columnName": "InstanceUrl",
"identifier": "InstanceName"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "ClientIp",
"identifier": "Address"
}
]
}
],
"eventGroupingSettings": {
"aggregationKind": "AlertPerResult"
},
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft%20Business%20Applications/Analytic%20Rules/Dataverse%20-%20Suspicious%20use%20of%20TDS%20endpoint.yaml",
"query": "let query_frequency = 1h;\nlet query_lookback = 14d;\nDataverseActivity\n| where TimeGenerated >= ago(query_frequency)\n| where Message == 'ExecutePowerBISql'\n| summarize FirstEvent = min(TimeGenerated) by UserId, ClientIp, InstanceUrl\n| join kind=inner(\n DataverseActivity\n | where TimeGenerated >= ago(query_lookback)\n | where Message == 'ExecutePowerBISql'\n | summarize UniqueUsers = dcount(UserId, 4) by InstanceUrl)\n on InstanceUrl\n| where UniqueUsers == 1\n| join kind=inner (\n SecurityAlert\n | where Entities has ('\"Type\":\"ip\"')\n | project AlertName, SystemAlertId, Entities\n | mv-expand todynamic(Entities)\n | where Entities.Type == \"ip\"\n | extend IPAddress = tostring(Entities.Address)\n | summarize SystemAlerts = make_set(SystemAlertId, 100), Alerts = make_set(AlertName, 100) by IPAddress)\n on $left.ClientIp == $right.IPAddress\n| extend\n CloudAppId = int(32780),\n AccountName = tostring(split(UserId, '@')[0]),\n UPNSuffix = tostring(split(UserId, '@')[1])\n| join kind = inner (\n SecurityAlert\n | where Entities has ('Type\":\"account\"')\n | project AlertName, SystemAlertId, Entities\n | mv-expand todynamic(Entities)\n | where Entities.Type == \"account\"\n | extend\n UPNSuffix = tostring(Entities.UPNSuffix),\n AccountName = tostring(Entities.Name)\n | summarize SystemAlerts = make_set(SystemAlertId, 100), Alerts = make_set(AlertName, 100) by AccountName, UPNSuffix\n | where isnotempty(AccountName) and isnotempty(UPNSuffix))\n on AccountName, UPNSuffix\n| summarize SystemAlerts = make_set(SystemAlerts, 100), Alerts = make_set(Alerts, 100) by FirstEvent, UserId, ClientIp, InstanceUrl, AccountName, UPNSuffix\n| extend CloudAppId = int(32780)\n| project\n FirstEvent,\n UserId,\n ClientIp,\n InstanceUrl,\n Alerts,\n SystemAlerts,\n CloudAppId,\n AccountName,\n UPNSuffix\n",
"queryFrequency": "PT1H",
"queryPeriod": "P14D",
"severity": "Low",
"status": "Available",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"Exfiltration",
"InitialAccess"
],
"techniques": [
"T1048",
"T1190"
],
"templateVersion": "3.2.0",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}