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

Dataverse - Export activity from terminated or notified employee

Back
Id0881b209-62c9-4b15-9f9a-e0c1d1b1eb7b
RulenameDataverse - Export activity from terminated or notified employee
DescriptionThis query identifies Dataverse export activity triggered by terminated, or employees about to leave the organization. This analytics rule uses the TerminatedEmployees watchlist template.
SeverityMedium
TacticsExfiltration
TechniquesT1567
T1048
Required data connectorsDataverse
KindScheduled
Query frequency1h
Query period1d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Business Applications/Analytic Rules/Dataverse - Export activity from terminated or notified employee.yaml
Version3.2.0
Arm template0881b209-62c9-4b15-9f9a-e0c1d1b1eb7b.json
Deploy To Azure
// Set a time period before employee terminatation date to search for export events
let termination_watch_period = 7d;
let query_frequency = 1h;
let exportEvents = dynamic(['ExportToExcel', 'ExportPdfDocument', 'ExportWordDocument', 'ExecutePowerBISql']);
MSBizAppsTerminatedEmployees
| where (UserState =~ "Terminated") or (UserState =~ "Notified" and TerminationDate <= startofday(now()) + termination_watch_period)
| join kind=inner (DataverseActivity
    | where TimeGenerated >= ago(query_frequency)
    | where Message in (exportEvents))
    on $left.UserPrincipalName == $right.UserId
| summarize
    FirstEvent = min(TimeGenerated),
    LastEvent = max(TimeGenerated),
    Event = make_set(Message, 4)
    by UserId, InstanceUrl, ClientIp, UserState
| extend
    CloudAppId = int(32780),
    AccountName = tostring(split(UserId, '@')[0]),
    UPNSuffix = tostring(split(UserId, '@')[1])
| project
    FirstEvent,
    LastEvent,
    UserId,
    ClientIp,
    UserState,
    InstanceUrl,
    CloudAppId,
    AccountName,
    UPNSuffix
eventGroupingSettings:
  aggregationKind: AlertPerResult
queryPeriod: 1d
name: Dataverse - Export activity from terminated or notified employee
status: Available
entityMappings:
- fieldMappings:
  - columnName: AccountName
    identifier: Name
  - columnName: UPNSuffix
    identifier: UPNSuffix
  entityType: Account
- fieldMappings:
  - columnName: ClientIp
    identifier: Address
  entityType: IP
- fieldMappings:
  - columnName: CloudAppId
    identifier: AppId
  - columnName: InstanceUrl
    identifier: InstanceName
  entityType: CloudApplication
alertDetailsOverride:
  alertDescriptionFormat: Export events where employee state found matching {{UserState}} found in {{InstanceUrl}}.
  alertDisplayNameFormat: 'Dataverse - Export events detected from a terminated employee in {{InstanceUrl}} '
tactics:
- Exfiltration
description: This query identifies Dataverse export activity triggered by terminated, or employees about to leave the organization. This analytics rule uses the TerminatedEmployees watchlist template.
severity: Medium
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Business Applications/Analytic Rules/Dataverse - Export activity from terminated or notified employee.yaml
requiredDataConnectors:
- connectorId: Dataverse
  dataTypes:
  - DataverseActivity
queryFrequency: 1h
id: 0881b209-62c9-4b15-9f9a-e0c1d1b1eb7b
version: 3.2.0
triggerThreshold: 0
query: |
  // Set a time period before employee terminatation date to search for export events
  let termination_watch_period = 7d;
  let query_frequency = 1h;
  let exportEvents = dynamic(['ExportToExcel', 'ExportPdfDocument', 'ExportWordDocument', 'ExecutePowerBISql']);
  MSBizAppsTerminatedEmployees
  | where (UserState =~ "Terminated") or (UserState =~ "Notified" and TerminationDate <= startofday(now()) + termination_watch_period)
  | join kind=inner (DataverseActivity
      | where TimeGenerated >= ago(query_frequency)
      | where Message in (exportEvents))
      on $left.UserPrincipalName == $right.UserId
  | summarize
      FirstEvent = min(TimeGenerated),
      LastEvent = max(TimeGenerated),
      Event = make_set(Message, 4)
      by UserId, InstanceUrl, ClientIp, UserState
  | extend
      CloudAppId = int(32780),
      AccountName = tostring(split(UserId, '@')[0]),
      UPNSuffix = tostring(split(UserId, '@')[1])
  | project
      FirstEvent,
      LastEvent,
      UserId,
      ClientIp,
      UserState,
      InstanceUrl,
      CloudAppId,
      AccountName,
      UPNSuffix  
relevantTechniques:
- T1567
- T1048
kind: Scheduled
triggerOperator: gt