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 to USB drive

Back
Idc5e75cb6-cea0-49c2-a998-da414035aac1
RulenameDataverse - Terminated employee exfiltration to USB drive
DescriptionIdentifies files downloaded from Dataverse by departing or terminated employees which are copied to USB mounted drives.
SeverityHigh
TacticsExfiltration
TechniquesT1052
Required data connectorsDataverse
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 to USB drive.yaml
Version3.2.0
Arm templatec5e75cb6-cea0-49c2-a998-da414035aac1.json
Deploy To Azure
let drive_mount_lookback = 14d;
let query_frequency = 1h;
DataverseActivity
| distinct InstanceUrl
| join kind=inner (DeviceFileEvents
    | where TimeGenerated >= ago(query_frequency))
    on $left.InstanceUrl == $right.FileOriginUrl
| join kind=inner (MSBizAppsTerminatedEmployees()) on $left.InitiatingProcessAccountUpn == $right.UserPrincipalName
| join kind=inner (DeviceEvents
    | where TimeGenerated >= ago(drive_mount_lookback)
    | where ActionType == "UsbDriveMounted"
    | extend DriveLetter = tostring(AdditionalFields.DriveLetter)
    | summarize MountedDriveLetters = make_set(DriveLetter, 26) by DeviceId, DeviceName)
    on DeviceId
| extend TargetDriveLetter = tostring(split(FolderPath, "\\")[0])
| where set_has_element(MountedDriveLetters, TargetDriveLetter)
| join kind=inner (DeviceInfo
    | summarize arg_max(TimeGenerated, DeviceId, PublicIP) by DeviceName)
    on DeviceId
| project-rename
    UserId = UserPrincipalName
| summarize LatestEvent = arg_max(TimeGenerated, *), Files = make_set(FileName, 100) by UserId, InstanceUrl
| extend
    CloudAppId = int(32780),
    AccountName = tostring(split(UserId, '@')[0]),
    UPNSuffix = tostring(split(UserId, '@')[1])
| project
    LatestEvent,
    UserId,
    PublicIP,
    Files,
    InstanceUrl,
    CloudAppId,
    AccountName,
    UPNSuffix
description: Identifies files downloaded from Dataverse by departing or terminated employees which are copied to USB mounted drives.
status: Available
queryPeriod: 14d
triggerThreshold: 0
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Business Applications/Analytic Rules/Dataverse - Terminated employee exfiltration to USB drive.yaml
id: c5e75cb6-cea0-49c2-a998-da414035aac1
kind: Scheduled
requiredDataConnectors:
- connectorId: Dataverse
  dataTypes:
  - DataverseActivity
- connectorId: MicrosoftThreatProtection
  dataTypes:
  - DeviceInfo
  - DeviceEvents
  - DeviceFileEvents
tactics:
- Exfiltration
severity: High
triggerOperator: gt
relevantTechniques:
- T1052
query: |
  let drive_mount_lookback = 14d;
  let query_frequency = 1h;
  DataverseActivity
  | distinct InstanceUrl
  | join kind=inner (DeviceFileEvents
      | where TimeGenerated >= ago(query_frequency))
      on $left.InstanceUrl == $right.FileOriginUrl
  | join kind=inner (MSBizAppsTerminatedEmployees()) on $left.InitiatingProcessAccountUpn == $right.UserPrincipalName
  | join kind=inner (DeviceEvents
      | where TimeGenerated >= ago(drive_mount_lookback)
      | where ActionType == "UsbDriveMounted"
      | extend DriveLetter = tostring(AdditionalFields.DriveLetter)
      | summarize MountedDriveLetters = make_set(DriveLetter, 26) by DeviceId, DeviceName)
      on DeviceId
  | extend TargetDriveLetter = tostring(split(FolderPath, "\\")[0])
  | where set_has_element(MountedDriveLetters, TargetDriveLetter)
  | join kind=inner (DeviceInfo
      | summarize arg_max(TimeGenerated, DeviceId, PublicIP) by DeviceName)
      on DeviceId
  | project-rename
      UserId = UserPrincipalName
  | summarize LatestEvent = arg_max(TimeGenerated, *), Files = make_set(FileName, 100) by UserId, InstanceUrl
  | extend
      CloudAppId = int(32780),
      AccountName = tostring(split(UserId, '@')[0]),
      UPNSuffix = tostring(split(UserId, '@')[1])
  | project
      LatestEvent,
      UserId,
      PublicIP,
      Files,
      InstanceUrl,
      CloudAppId,
      AccountName,
      UPNSuffix  
eventGroupingSettings:
  aggregationKind: AlertPerResult
version: 3.2.0
queryFrequency: 1h
alertDetailsOverride:
  alertDescriptionFormat: '{{UserId}} , on the TerminatedUsers watchlist, was found to copy files to a USB mounted drive.'
  alertDisplayNameFormat: Dataverse - terminated user copied files from {{InstanceUrl}} to USB
name: Dataverse - Terminated employee exfiltration to USB drive
entityMappings:
- fieldMappings:
  - columnName: AccountName
    identifier: Name
  - columnName: UPNSuffix
    identifier: UPNSuffix
  entityType: Account
- fieldMappings:
  - columnName: PublicIP
    identifier: Address
  entityType: IP
- fieldMappings:
  - columnName: CloudAppId
    identifier: AppId
  - columnName: InstanceUrl
    identifier: InstanceName
  entityType: CloudApplication
customDetails: {}
{
  "$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/c5e75cb6-cea0-49c2-a998-da414035aac1')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/c5e75cb6-cea0-49c2-a998-da414035aac1')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "{{UserId}} , on the TerminatedUsers watchlist, was found to copy files to a USB mounted drive.",
          "alertDisplayNameFormat": "Dataverse - terminated user copied files from {{InstanceUrl}} to USB"
        },
        "alertRuleTemplateName": "c5e75cb6-cea0-49c2-a998-da414035aac1",
        "customDetails": {},
        "description": "Identifies files downloaded from Dataverse by departing or terminated employees which are copied to USB mounted drives.",
        "displayName": "Dataverse - Terminated employee exfiltration to USB drive",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "AccountName",
                "identifier": "Name"
              },
              {
                "columnName": "UPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "PublicIP",
                "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 to USB drive.yaml",
        "query": "let drive_mount_lookback = 14d;\nlet query_frequency = 1h;\nDataverseActivity\n| distinct InstanceUrl\n| join kind=inner (DeviceFileEvents\n    | where TimeGenerated >= ago(query_frequency))\n    on $left.InstanceUrl == $right.FileOriginUrl\n| join kind=inner (MSBizAppsTerminatedEmployees()) on $left.InitiatingProcessAccountUpn == $right.UserPrincipalName\n| join kind=inner (DeviceEvents\n    | where TimeGenerated >= ago(drive_mount_lookback)\n    | where ActionType == \"UsbDriveMounted\"\n    | extend DriveLetter = tostring(AdditionalFields.DriveLetter)\n    | summarize MountedDriveLetters = make_set(DriveLetter, 26) by DeviceId, DeviceName)\n    on DeviceId\n| extend TargetDriveLetter = tostring(split(FolderPath, \"\\\\\")[0])\n| where set_has_element(MountedDriveLetters, TargetDriveLetter)\n| join kind=inner (DeviceInfo\n    | summarize arg_max(TimeGenerated, DeviceId, PublicIP) by DeviceName)\n    on DeviceId\n| project-rename\n    UserId = UserPrincipalName\n| summarize LatestEvent = arg_max(TimeGenerated, *), Files = make_set(FileName, 100) by UserId, InstanceUrl\n| extend\n    CloudAppId = int(32780),\n    AccountName = tostring(split(UserId, '@')[0]),\n    UPNSuffix = tostring(split(UserId, '@')[1])\n| project\n    LatestEvent,\n    UserId,\n    PublicIP,\n    Files,\n    InstanceUrl,\n    CloudAppId,\n    AccountName,\n    UPNSuffix\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "P14D",
        "severity": "High",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "Exfiltration"
        ],
        "techniques": [
          "T1052"
        ],
        "templateVersion": "3.2.0",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}