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
relevantTechniques:
- T1639
- T1567
name: Dataverse - Terminated employee exfiltration over email
queryPeriod: 14d
triggerThreshold: 0
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
id: de039242-47e0-43fa-84d7-b6be24305349
eventGroupingSettings:
  aggregationKind: AlertPerResult
severity: High
requiredDataConnectors:
- dataTypes:
  - EmailEvents
  connectorId: MicrosoftThreatProtection
- dataTypes:
  - SecurityAlert
  connectorId: AzureActiveDirectoryIdentityProtection
- dataTypes:
  - IdentityInfo
  connectorId: IdentityInfo
description: This query identifies Dataverse exfiltration via email by terminated employees.
version: 3.2.0
status: Available
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
tactics:
- Exfiltration
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
triggerOperator: gt
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Business Applications/Analytic Rules/Dataverse - Terminated employee exfiltration over email.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/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"
    }
  ]
}