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
relevantTechniques:
- T1052
name: Dataverse - Terminated employee exfiltration to USB drive
queryPeriod: 14d
triggerThreshold: 0
customDetails: {}
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
id: c5e75cb6-cea0-49c2-a998-da414035aac1
eventGroupingSettings:
  aggregationKind: AlertPerResult
severity: High
requiredDataConnectors:
- dataTypes:
  - DataverseActivity
  connectorId: Dataverse
- dataTypes:
  - DeviceInfo
  - DeviceEvents
  - DeviceFileEvents
  connectorId: MicrosoftThreatProtection
description: Identifies files downloaded from Dataverse by departing or terminated employees which are copied to USB mounted drives.
version: 3.2.0
status: Available
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
tactics:
- Exfiltration
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  
kind: Scheduled
triggerOperator: gt
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Business Applications/Analytic Rules/Dataverse - Terminated employee exfiltration to USB drive.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/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"
    }
  ]
}