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
relevantTechniques:
- T1078
- T0866
- T0819
- T1036
name: Dataverse - New user agent type that was not used before
queryPeriod: 14d
triggerThreshold: 0
alertDetailsOverride:
  alertDescriptionFormat: |
    {{UserId}} with new agent not seen previously in the Dataverse activity log.
    Agent: {{UserAgent}}
    Latest IP: {{LatestIP}}    
  alertDisplayNameFormat: 'Dataverse - new user agent detected in {{{InstanceUrl}} '
id: 34a5d79b-8f9a-420c-aa64-7f4d262ac29a
eventGroupingSettings:
  aggregationKind: AlertPerResult
severity: Low
requiredDataConnectors:
- dataTypes:
  - DataverseActivity
  connectorId: Dataverse
description: Identifies users accessing Dataverse from a User Agent that has not been seen in any Dataverse instance in the last 14 days.
version: 3.2.0
status: Available
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
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  
kind: Scheduled
triggerOperator: gt
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
queryFrequency: 1h
{
  "$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"
    }
  ]
}