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

Dataverse - New sign-in from an unauthorized domain

Back
Id4c1c9aee-8e44-4bb9-bd53-f3e7d6761282
RulenameDataverse - New sign-in from an unauthorized domain
DescriptionIdentifies Dataverse sign-in activity originating from users with UPN suffixes that have not been seen previously in the last 14 days and are not present on a predefined list of authorized domains. Common internal Power Platform system users are excluded by default.
SeverityMedium
TacticsInitialAccess
TechniquesT1078
T1190
T1133
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 sign-in from an unauthorized domain.yaml
Version3.2.0
Arm template4c1c9aee-8e44-4bb9-bd53-f3e7d6761282.json
Deploy To Azure
// Allow list of UPN suffixes allowed by the organization.
let allowed_domains = dynamic([
    'onmicrosoft.com',
    'microsoft.com'
    ]);
// All list of users allowed by the organization
let allowed_users = dynamic([
    'user1@mydomain.com',
    'user2@mydomain.com'
    ]);
let query_frequency = 1h;
let query_lookback = 14d;
let historical_users = DataverseActivity
    | where TimeGenerated between(ago(query_lookback) .. ago(query_frequency))
    | where Message == 'UserSignIn'
    | summarize by UserId;
DataverseActivity
| where TimeGenerated >= ago (query_frequency)
| where Message == 'UserSignIn'
| join kind=leftanti (historical_users) on UserId
| summarize FirstEvent = min(TimeGenerated), LastEvent = max(TimeGenerated) by UserId, ClientIp, InstanceUrl
| where isnotempty(ClientIp)
| extend CloudAppId = int(32780)
| extend AccountName = tostring(split(UserId, '@')[0])
| extend UPNSuffix = tostring(split(UserId, '@')[1])
| where UPNSuffix !in (allowed_domains) and UserId !in (allowed_users)
| project
    FirstEvent,
    LastEvent,
    UserId,
    ClientIp,
    InstanceUrl,
    AccountName,
    UPNSuffix,
    CloudAppId
description: Identifies Dataverse sign-in activity originating from users with UPN suffixes that have not been seen previously in the last 14 days and are not present on a predefined list of authorized domains. Common internal Power Platform system users are excluded by default.
alertDetailsOverride:
  alertDescriptionFormat: New user sign-in activity was detected in {{InstanceUrl}} originating from user {{UserId}}. This user's UPN suffix is not on the authorized list of domains.
  alertDisplayNameFormat: Dataverse - Unauthorized sign-in activity
version: 3.2.0
relevantTechniques:
- T1078
- T1190
- T1133
kind: Scheduled
requiredDataConnectors:
- connectorId: Dataverse
  dataTypes:
  - DataverseActivity
entityMappings:
- fieldMappings:
  - identifier: Name
    columnName: AccountName
  - identifier: UPNSuffix
    columnName: UPNSuffix
  entityType: Account
- fieldMappings:
  - identifier: Address
    columnName: ClientIp
  entityType: IP
- fieldMappings:
  - identifier: AppId
    columnName: CloudAppId
  - identifier: InstanceName
    columnName: InstanceUrl
  entityType: CloudApplication
triggerThreshold: 0
eventGroupingSettings:
  aggregationKind: SingleAlert
id: 4c1c9aee-8e44-4bb9-bd53-f3e7d6761282
tactics:
- InitialAccess
queryPeriod: 14d
query: |
  // Allow list of UPN suffixes allowed by the organization.
  let allowed_domains = dynamic([
      'onmicrosoft.com',
      'microsoft.com'
      ]);
  // All list of users allowed by the organization
  let allowed_users = dynamic([
      'user1@mydomain.com',
      'user2@mydomain.com'
      ]);
  let query_frequency = 1h;
  let query_lookback = 14d;
  let historical_users = DataverseActivity
      | where TimeGenerated between(ago(query_lookback) .. ago(query_frequency))
      | where Message == 'UserSignIn'
      | summarize by UserId;
  DataverseActivity
  | where TimeGenerated >= ago (query_frequency)
  | where Message == 'UserSignIn'
  | join kind=leftanti (historical_users) on UserId
  | summarize FirstEvent = min(TimeGenerated), LastEvent = max(TimeGenerated) by UserId, ClientIp, InstanceUrl
  | where isnotempty(ClientIp)
  | extend CloudAppId = int(32780)
  | extend AccountName = tostring(split(UserId, '@')[0])
  | extend UPNSuffix = tostring(split(UserId, '@')[1])
  | where UPNSuffix !in (allowed_domains) and UserId !in (allowed_users)
  | project
      FirstEvent,
      LastEvent,
      UserId,
      ClientIp,
      InstanceUrl,
      AccountName,
      UPNSuffix,
      CloudAppId  
severity: Medium
name: Dataverse - New sign-in from an unauthorized domain
queryFrequency: 1h
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Business Applications/Analytic Rules/Dataverse - New sign-in from an unauthorized domain.yaml
triggerOperator: gt
status: Available
{
  "$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/4c1c9aee-8e44-4bb9-bd53-f3e7d6761282')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/4c1c9aee-8e44-4bb9-bd53-f3e7d6761282')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "New user sign-in activity was detected in {{InstanceUrl}} originating from user {{UserId}}. This user's UPN suffix is not on the authorized list of domains.",
          "alertDisplayNameFormat": "Dataverse - Unauthorized sign-in activity"
        },
        "alertRuleTemplateName": "4c1c9aee-8e44-4bb9-bd53-f3e7d6761282",
        "customDetails": null,
        "description": "Identifies Dataverse sign-in activity originating from users with UPN suffixes that have not been seen previously in the last 14 days and are not present on a predefined list of authorized domains. Common internal Power Platform system users are excluded by default.",
        "displayName": "Dataverse - New sign-in from an unauthorized domain",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "AccountName",
                "identifier": "Name"
              },
              {
                "columnName": "UPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "ClientIp",
                "identifier": "Address"
              }
            ]
          },
          {
            "entityType": "CloudApplication",
            "fieldMappings": [
              {
                "columnName": "CloudAppId",
                "identifier": "AppId"
              },
              {
                "columnName": "InstanceUrl",
                "identifier": "InstanceName"
              }
            ]
          }
        ],
        "eventGroupingSettings": {
          "aggregationKind": "SingleAlert"
        },
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Business Applications/Analytic Rules/Dataverse - New sign-in from an unauthorized domain.yaml",
        "query": "// Allow list of UPN suffixes allowed by the organization.\nlet allowed_domains = dynamic([\n    'onmicrosoft.com',\n    'microsoft.com'\n    ]);\n// All list of users allowed by the organization\nlet allowed_users = dynamic([\n    'user1@mydomain.com',\n    'user2@mydomain.com'\n    ]);\nlet query_frequency = 1h;\nlet query_lookback = 14d;\nlet historical_users = DataverseActivity\n    | where TimeGenerated between(ago(query_lookback) .. ago(query_frequency))\n    | where Message == 'UserSignIn'\n    | summarize by UserId;\nDataverseActivity\n| where TimeGenerated >= ago (query_frequency)\n| where Message == 'UserSignIn'\n| join kind=leftanti (historical_users) on UserId\n| summarize FirstEvent = min(TimeGenerated), LastEvent = max(TimeGenerated) by UserId, ClientIp, InstanceUrl\n| where isnotempty(ClientIp)\n| extend CloudAppId = int(32780)\n| extend AccountName = tostring(split(UserId, '@')[0])\n| extend UPNSuffix = tostring(split(UserId, '@')[1])\n| where UPNSuffix !in (allowed_domains) and UserId !in (allowed_users)\n| project\n    FirstEvent,\n    LastEvent,\n    UserId,\n    ClientIp,\n    InstanceUrl,\n    AccountName,\n    UPNSuffix,\n    CloudAppId\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "P14D",
        "severity": "Medium",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "InitialAccess"
        ],
        "techniques": [
          "T1078",
          "T1133",
          "T1190"
        ],
        "templateVersion": "3.2.0",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}