Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

Dataverse - New user agent type that was not used before

Back
Id34a5d79b-8f9a-420c-aa64-7f4d262ac29a
RulenameDataverse - New user agent type that was not used before
DescriptionIdentifies users accessing Dataverse from a User Agent that has not been seen in any Dataverse instance in the last 14 days.
SeverityLow
TacticsInitialAccess
DefenseEvasion
TechniquesT1078
T0866
T0819
T1036
Required data connectorsDataverse
KindScheduled
Query frequency1h
Query period14d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Business Applications/Analytic Rules/Dataverse - New user agent type that was not used before.yaml
Version3.2.0
Arm template34a5d79b-8f9a-420c-aa64-7f4d262ac29a.json
Deploy To Azure
let query_lookback = 14d;
let query_frequency = 1h;
let known_useragents = dynamic([
    // Enter known user agents to exclude.
    // example:
    // "Agent1", "Agent2", "Agent3"
    ]);
DataverseActivity
| where TimeGenerated between(ago(query_lookback) .. ago(query_frequency))
| where isnotempty(UserAgent)
| summarize by UserAgent
| join kind = rightanti (DataverseActivity
    | where TimeGenerated > ago(query_frequency)
    | where not (UserId has_any ("@onmicrosoft.com", "@microsoft.com", "Unknown"))
    | where isnotempty(UserAgent)
    | where UserAgent !in~ (known_useragents)
    | where UserAgent !hasprefix "azure-logic-apps" and UserAgent !hasprefix "PowerApps")
    on UserAgent
// Exclude user agents with a render agent to reduce noise.
| join kind = leftanti(
    DataverseActivity
    | where TimeGenerated > ago(query_frequency)
    | where UserAgent has_any ("Gecko", "WebKit", "Presto", "Trident", "EdgeHTML", "Blink"))
    on UserAgent
| summarize
    FirstSeen = min(TimeGenerated),
    LatestIP = arg_max(ClientIp, TimeGenerated)
    by UserAgent, UserId, InstanceUrl
| extend
    AccountName = tostring(split(UserId, '@')[0]),
    UPNSuffix = tostring(split(UserId, '@')[1]),
    CloudAppId = int(32780)
| project
    FirstSeen,
    UserId,
    UserAgent,
    LatestIP,
    InstanceUrl,
    CloudAppId,
    AccountName,
    UPNSuffix
kind: Scheduled
id: 34a5d79b-8f9a-420c-aa64-7f4d262ac29a
entityMappings:
- fieldMappings:
  - identifier: Name
    columnName: AccountName
  - identifier: UPNSuffix
    columnName: UPNSuffix
  entityType: Account
- fieldMappings:
  - identifier: AppId
    columnName: CloudAppId
  - identifier: InstanceName
    columnName: InstanceUrl
  entityType: CloudApplication
- fieldMappings:
  - identifier: Address
    columnName: LatestIP
  entityType: IP
name: Dataverse - New user agent type that was not used before
severity: Low
triggerOperator: gt
tactics:
- InitialAccess
- DefenseEvasion
query: |
  let query_lookback = 14d;
  let query_frequency = 1h;
  let known_useragents = dynamic([
      // Enter known user agents to exclude.
      // example:
      // "Agent1", "Agent2", "Agent3"
      ]);
  DataverseActivity
  | where TimeGenerated between(ago(query_lookback) .. ago(query_frequency))
  | where isnotempty(UserAgent)
  | summarize by UserAgent
  | join kind = rightanti (DataverseActivity
      | where TimeGenerated > ago(query_frequency)
      | where not (UserId has_any ("@onmicrosoft.com", "@microsoft.com", "Unknown"))
      | where isnotempty(UserAgent)
      | where UserAgent !in~ (known_useragents)
      | where UserAgent !hasprefix "azure-logic-apps" and UserAgent !hasprefix "PowerApps")
      on UserAgent
  // Exclude user agents with a render agent to reduce noise.
  | join kind = leftanti(
      DataverseActivity
      | where TimeGenerated > ago(query_frequency)
      | where UserAgent has_any ("Gecko", "WebKit", "Presto", "Trident", "EdgeHTML", "Blink"))
      on UserAgent
  | summarize
      FirstSeen = min(TimeGenerated),
      LatestIP = arg_max(ClientIp, TimeGenerated)
      by UserAgent, UserId, InstanceUrl
  | extend
      AccountName = tostring(split(UserId, '@')[0]),
      UPNSuffix = tostring(split(UserId, '@')[1]),
      CloudAppId = int(32780)
  | project
      FirstSeen,
      UserId,
      UserAgent,
      LatestIP,
      InstanceUrl,
      CloudAppId,
      AccountName,
      UPNSuffix  
triggerThreshold: 0
status: Available
description: Identifies users accessing Dataverse from a User Agent that has not been seen in any Dataverse instance in the last 14 days.
eventGroupingSettings:
  aggregationKind: AlertPerResult
queryFrequency: 1h
queryPeriod: 14d
relevantTechniques:
- T1078
- T0866
- T0819
- T1036
version: 3.2.0
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Business Applications/Analytic Rules/Dataverse - New user agent type that was not used before.yaml
requiredDataConnectors:
- connectorId: Dataverse
  dataTypes:
  - DataverseActivity
alertDetailsOverride:
  alertDisplayNameFormat: 'Dataverse - new user agent detected in {{{InstanceUrl}} '
  alertDescriptionFormat: |
    {{UserId}} with new agent not seen previously in the Dataverse activity log.
    Agent: {{UserAgent}}
    Latest IP: {{LatestIP}}    
{
  "$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/34a5d79b-8f9a-420c-aa64-7f4d262ac29a')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/34a5d79b-8f9a-420c-aa64-7f4d262ac29a')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "{{UserId}} with new agent not seen previously in the Dataverse activity log.\nAgent: {{UserAgent}}\nLatest IP: {{LatestIP}}\n",
          "alertDisplayNameFormat": "Dataverse - new user agent detected in {{{InstanceUrl}} "
        },
        "alertRuleTemplateName": "34a5d79b-8f9a-420c-aa64-7f4d262ac29a",
        "customDetails": null,
        "description": "Identifies users accessing Dataverse from a User Agent that has not been seen in any Dataverse instance in the last 14 days.",
        "displayName": "Dataverse - New user agent type that was not used before",
        "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": "LatestIP",
                "identifier": "Address"
              }
            ]
          }
        ],
        "eventGroupingSettings": {
          "aggregationKind": "AlertPerResult"
        },
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Business Applications/Analytic Rules/Dataverse - New user agent type that was not used before.yaml",
        "query": "let query_lookback = 14d;\nlet query_frequency = 1h;\nlet known_useragents = dynamic([\n    // Enter known user agents to exclude.\n    // example:\n    // \"Agent1\", \"Agent2\", \"Agent3\"\n    ]);\nDataverseActivity\n| where TimeGenerated between(ago(query_lookback) .. ago(query_frequency))\n| where isnotempty(UserAgent)\n| summarize by UserAgent\n| join kind = rightanti (DataverseActivity\n    | where TimeGenerated > ago(query_frequency)\n    | where not (UserId has_any (\"@onmicrosoft.com\", \"@microsoft.com\", \"Unknown\"))\n    | where isnotempty(UserAgent)\n    | where UserAgent !in~ (known_useragents)\n    | where UserAgent !hasprefix \"azure-logic-apps\" and UserAgent !hasprefix \"PowerApps\")\n    on UserAgent\n// Exclude user agents with a render agent to reduce noise.\n| join kind = leftanti(\n    DataverseActivity\n    | where TimeGenerated > ago(query_frequency)\n    | where UserAgent has_any (\"Gecko\", \"WebKit\", \"Presto\", \"Trident\", \"EdgeHTML\", \"Blink\"))\n    on UserAgent\n| summarize\n    FirstSeen = min(TimeGenerated),\n    LatestIP = arg_max(ClientIp, TimeGenerated)\n    by UserAgent, UserId, InstanceUrl\n| extend\n    AccountName = tostring(split(UserId, '@')[0]),\n    UPNSuffix = tostring(split(UserId, '@')[1]),\n    CloudAppId = int(32780)\n| project\n    FirstSeen,\n    UserId,\n    UserAgent,\n    LatestIP,\n    InstanceUrl,\n    CloudAppId,\n    AccountName,\n    UPNSuffix\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "P14D",
        "severity": "Low",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "DefenseEvasion",
          "InitialAccess"
        ],
        "techniques": [
          "T1036",
          "T1078"
        ],
        "templateVersion": "3.2.0",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}