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

Dataverse - Terminated employee exfiltration over email

Back
Idde039242-47e0-43fa-84d7-b6be24305349
RulenameDataverse - Terminated employee exfiltration over email
DescriptionThis query identifies Dataverse exfiltration via email by terminated employees.
SeverityHigh
TacticsExfiltration
TechniquesT1639
T1567
Required data connectorsAzureActiveDirectoryIdentityProtection
IdentityInfo
MicrosoftThreatProtection
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 - Terminated employee exfiltration over email.yaml
Version3.2.0
Arm templatede039242-47e0-43fa-84d7-b6be24305349.json
Deploy To Azure
// Note this detection relies upon the user's UPN matching their email address.
// UEBA can provide more accurate data if enabled.
let query_frequency = 1h;
let allowed_destination_smtp_domains = dynamic([
// Specify a list of recipient domains to exclude from alerting.
// Example:
// "microsoft.com", "contoso.com"
    ]);
let exfiltration_alert_users = SecurityAlert
    | where Tactics has 'Exfiltration' and Entities has_all ('account', '32780')
    | mv-expand DataverseEntities = todynamic(Entities)
    | where DataverseEntities.AppId == 32780
    | extend InstanceUrl = tostring(DataverseEntities.InstanceName)
    | mv-expand AccountEntities = todynamic(Entities)
    | where AccountEntities.Type == 'account'
    | extend
        AccountName = tostring(AccountEntities.Name),
        UPNSuffix = tostring(AccountEntities.UPNSuffix)
    | summarize InstanceUrls = make_set(InstanceUrl, 100) by AccountName, UPNSuffix
    | extend UserId = tolower(strcat(AccountName, "@", UPNSuffix));
exfiltration_alert_users
| join kind=inner (
    MSBizAppsTerminatedEmployees
    | project UserId = tolower(UserPrincipalName), NotificationDate
    | where startofday(NotificationDate) <= startofday(now()))
    // Uncomment the below KQL if UEBA is available to gain more accurate
    // email address data:
    // | join kind=leftouter (_ASIM_IdentityInfo) on $left.UserId == $right.Username
    // | extend UserId = iif(UserId == UserMailAddress or isempty(UserMailAddress), UserId, UserMailAddress))
    on UserId
| join kind=inner (
    EmailEvents
    | where TimeGenerated >= ago (query_frequency)
    | where EmailDirection == "Outbound" and AttachmentCount > 0
    | extend RecipientDomain = tolower(split(RecipientEmailAddress, '@')[1])
    | where RecipientDomain !in (allowed_destination_smtp_domains)
    | summarize
        RecipientAddresses = make_set(RecipientEmailAddress, 1000),
        Subject = make_set(Subject, 1000)
        by SenderAddress = tolower(SenderMailFromAddress), SenderIPv4)
    on $left.UserId == $right.SenderAddress
| mv-expand InstanceUrl = InstanceUrls to typeof(string)
| extend
    CloudAppId = int(32780),
    AccountName = tostring(split(UserId, "@")[0]),
    UPNSuffix = tostring(split(UserId, "@")[1])
| project
    UserId,
    InstanceUrl,
    SenderIPv4,
    RecipientAddresses,
    Subject,
    AccountName,
    UPNSuffix,
    CloudAppId
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
  dataTypes:
  - EmailEvents
- connectorId: AzureActiveDirectoryIdentityProtection
  dataTypes:
  - SecurityAlert
- connectorId: IdentityInfo
  dataTypes:
  - IdentityInfo
alertDetailsOverride:
  alertDisplayNameFormat: Email attachment sent externally by terminated user following Dataverse exfiltration alerts
  alertDescriptionFormat: 'Departing or terminated user {{UserId}} was found to send email to external domains not on the allowed list: {{RecipientAddresses}}'
query: |
  // Note this detection relies upon the user's UPN matching their email address.
  // UEBA can provide more accurate data if enabled.
  let query_frequency = 1h;
  let allowed_destination_smtp_domains = dynamic([
  // Specify a list of recipient domains to exclude from alerting.
  // Example:
  // "microsoft.com", "contoso.com"
      ]);
  let exfiltration_alert_users = SecurityAlert
      | where Tactics has 'Exfiltration' and Entities has_all ('account', '32780')
      | mv-expand DataverseEntities = todynamic(Entities)
      | where DataverseEntities.AppId == 32780
      | extend InstanceUrl = tostring(DataverseEntities.InstanceName)
      | mv-expand AccountEntities = todynamic(Entities)
      | where AccountEntities.Type == 'account'
      | extend
          AccountName = tostring(AccountEntities.Name),
          UPNSuffix = tostring(AccountEntities.UPNSuffix)
      | summarize InstanceUrls = make_set(InstanceUrl, 100) by AccountName, UPNSuffix
      | extend UserId = tolower(strcat(AccountName, "@", UPNSuffix));
  exfiltration_alert_users
  | join kind=inner (
      MSBizAppsTerminatedEmployees
      | project UserId = tolower(UserPrincipalName), NotificationDate
      | where startofday(NotificationDate) <= startofday(now()))
      // Uncomment the below KQL if UEBA is available to gain more accurate
      // email address data:
      // | join kind=leftouter (_ASIM_IdentityInfo) on $left.UserId == $right.Username
      // | extend UserId = iif(UserId == UserMailAddress or isempty(UserMailAddress), UserId, UserMailAddress))
      on UserId
  | join kind=inner (
      EmailEvents
      | where TimeGenerated >= ago (query_frequency)
      | where EmailDirection == "Outbound" and AttachmentCount > 0
      | extend RecipientDomain = tolower(split(RecipientEmailAddress, '@')[1])
      | where RecipientDomain !in (allowed_destination_smtp_domains)
      | summarize
          RecipientAddresses = make_set(RecipientEmailAddress, 1000),
          Subject = make_set(Subject, 1000)
          by SenderAddress = tolower(SenderMailFromAddress), SenderIPv4)
      on $left.UserId == $right.SenderAddress
  | mv-expand InstanceUrl = InstanceUrls to typeof(string)
  | extend
      CloudAppId = int(32780),
      AccountName = tostring(split(UserId, "@")[0]),
      UPNSuffix = tostring(split(UserId, "@")[1])
  | project
      UserId,
      InstanceUrl,
      SenderIPv4,
      RecipientAddresses,
      Subject,
      AccountName,
      UPNSuffix,
      CloudAppId  
kind: Scheduled
severity: High
eventGroupingSettings:
  aggregationKind: AlertPerResult
triggerThreshold: 0
queryFrequency: 1h
id: de039242-47e0-43fa-84d7-b6be24305349
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Business Applications/Analytic Rules/Dataverse - Terminated employee exfiltration over email.yaml
tactics:
- Exfiltration
triggerOperator: gt
description: This query identifies Dataverse exfiltration via email by terminated employees.
status: Available
queryPeriod: 14d
name: Dataverse - Terminated employee exfiltration over email
entityMappings:
- entityType: Account
  fieldMappings:
  - identifier: Name
    columnName: AccountName
  - identifier: UPNSuffix
    columnName: UPNSuffix
- entityType: IP
  fieldMappings:
  - identifier: Address
    columnName: SenderIPv4
- entityType: CloudApplication
  fieldMappings:
  - identifier: AppId
    columnName: CloudAppId
  - identifier: InstanceName
    columnName: InstanceUrl
relevantTechniques:
- T1639
- T1567
version: 3.2.0
{
  "$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/de039242-47e0-43fa-84d7-b6be24305349')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/de039242-47e0-43fa-84d7-b6be24305349')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "Departing or terminated user {{UserId}} was found to send email to external domains not on the allowed list: {{RecipientAddresses}}",
          "alertDisplayNameFormat": "Email attachment sent externally by terminated user following Dataverse exfiltration alerts"
        },
        "alertRuleTemplateName": "de039242-47e0-43fa-84d7-b6be24305349",
        "customDetails": null,
        "description": "This query identifies Dataverse exfiltration via email by terminated employees.",
        "displayName": "Dataverse - Terminated employee exfiltration over email",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "AccountName",
                "identifier": "Name"
              },
              {
                "columnName": "UPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "SenderIPv4",
                "identifier": "Address"
              }
            ]
          },
          {
            "entityType": "CloudApplication",
            "fieldMappings": [
              {
                "columnName": "CloudAppId",
                "identifier": "AppId"
              },
              {
                "columnName": "InstanceUrl",
                "identifier": "InstanceName"
              }
            ]
          }
        ],
        "eventGroupingSettings": {
          "aggregationKind": "AlertPerResult"
        },
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Business Applications/Analytic Rules/Dataverse - Terminated employee exfiltration over email.yaml",
        "query": "// Note this detection relies upon the user's UPN matching their email address.\n// UEBA can provide more accurate data if enabled.\nlet query_frequency = 1h;\nlet allowed_destination_smtp_domains = dynamic([\n// Specify a list of recipient domains to exclude from alerting.\n// Example:\n// \"microsoft.com\", \"contoso.com\"\n    ]);\nlet exfiltration_alert_users = SecurityAlert\n    | where Tactics has 'Exfiltration' and Entities has_all ('account', '32780')\n    | mv-expand DataverseEntities = todynamic(Entities)\n    | where DataverseEntities.AppId == 32780\n    | extend InstanceUrl = tostring(DataverseEntities.InstanceName)\n    | mv-expand AccountEntities = todynamic(Entities)\n    | where AccountEntities.Type == 'account'\n    | extend\n        AccountName = tostring(AccountEntities.Name),\n        UPNSuffix = tostring(AccountEntities.UPNSuffix)\n    | summarize InstanceUrls = make_set(InstanceUrl, 100) by AccountName, UPNSuffix\n    | extend UserId = tolower(strcat(AccountName, \"@\", UPNSuffix));\nexfiltration_alert_users\n| join kind=inner (\n    MSBizAppsTerminatedEmployees\n    | project UserId = tolower(UserPrincipalName), NotificationDate\n    | where startofday(NotificationDate) <= startofday(now()))\n    // Uncomment the below KQL if UEBA is available to gain more accurate\n    // email address data:\n    // | join kind=leftouter (_ASIM_IdentityInfo) on $left.UserId == $right.Username\n    // | extend UserId = iif(UserId == UserMailAddress or isempty(UserMailAddress), UserId, UserMailAddress))\n    on UserId\n| join kind=inner (\n    EmailEvents\n    | where TimeGenerated >= ago (query_frequency)\n    | where EmailDirection == \"Outbound\" and AttachmentCount > 0\n    | extend RecipientDomain = tolower(split(RecipientEmailAddress, '@')[1])\n    | where RecipientDomain !in (allowed_destination_smtp_domains)\n    | summarize\n        RecipientAddresses = make_set(RecipientEmailAddress, 1000),\n        Subject = make_set(Subject, 1000)\n        by SenderAddress = tolower(SenderMailFromAddress), SenderIPv4)\n    on $left.UserId == $right.SenderAddress\n| mv-expand InstanceUrl = InstanceUrls to typeof(string)\n| extend\n    CloudAppId = int(32780),\n    AccountName = tostring(split(UserId, \"@\")[0]),\n    UPNSuffix = tostring(split(UserId, \"@\")[1])\n| project\n    UserId,\n    InstanceUrl,\n    SenderIPv4,\n    RecipientAddresses,\n    Subject,\n    AccountName,\n    UPNSuffix,\n    CloudAppId\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "P14D",
        "severity": "High",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "Exfiltration"
        ],
        "techniques": [
          "T1567"
        ],
        "templateVersion": "3.2.0",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}