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

Dataverse - User bulk retrieval outside normal activity

Back
Id08cb7ffc-59c6-4e7d-88e0-327371c9431b
RulenameDataverse - User bulk retrieval outside normal activity
DescriptionIdentifies users retrieving significantly more records from Dataverse than they have previously in the past 2 weeks.
SeverityLow
TacticsExfiltration
TechniquesT1048
Required data connectorsDataverse
KindScheduled
Query frequency1d
Query period14d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Business Applications/Analytic Rules/Dataverse - User bulk retrieval outside normal activity.yaml
Version3.2.0
Arm template08cb7ffc-59c6-4e7d-88e0-327371c9431b.json
Deploy To Azure
let baseline_time = 14d;
let detection_time = 1d;
DataverseActivity
| where TimeGenerated between(ago(baseline_time) .. ago(detection_time - 1d))
| where Message == "RetrieveMultiple"
| extend numQueryCount = todouble(QueryResults)
| extend QueryCount = iif(QueryResults contains ",", todouble(countof(tostring(QueryResults), ',') + 1), numQueryCount)
| extend QueryCount = iif(isnotempty(QueryCount), QueryCount, double(1))
| summarize sum(QueryCount) by UserId
| extend HistoricalBaseline = sum_QueryCount
| join kind=inner (
    DataverseActivity
    | where TimeGenerated > ago(detection_time)
    | where Message == "RetrieveMultiple"
    | extend numQueryCount = todouble(QueryResults)
    | extend QueryCount = iif(QueryResults contains ",", todouble(countof(tostring(QueryResults), ',') + 1), numQueryCount)
    | extend QueryCount = iif(isnotempty(QueryCount), QueryCount, double(1))
    | summarize sum(QueryCount) by UserId
    | extend CurrentExportRate = sum_QueryCount)
    on UserId
| where CurrentExportRate > HistoricalBaseline
| project UserId, HistoricalBaseline, CurrentExportRate
| join kind=inner(
    DataverseActivity
    | where TimeGenerated > ago(detection_time)
    | where Message == "RetrieveMultiple"
    | extend numQueryCount = todouble(QueryResults)
    | extend QueryCount = iif(QueryResults contains ",", todouble(countof(tostring(QueryResults), ',') + 1), numQueryCount)
    | extend QueryCount = iif(isnotempty(QueryCount), QueryCount, double(1)))
    on UserId
| summarize
    QuerySizes = make_set(QueryCount),
    MostRecentQuery = max(TimeGenerated),
    IPs = make_set(ClientIp),
    UserAgents = make_set(UserAgent),
    Entities = make_set(EntityName),
    Queries = make_set(Query)
    by UserId, InstanceUrl, HistoricalBaseline, CurrentExportRate
| extend
    AccountName = tostring(split(UserId, '@')[0]),
    UPNSuffix = tostring(split(UserId, '@')[1]),
    CloudAppId = int(32780)
| project
    MostRecentQuery,
    UserId,
    IPs,
    UserAgents,
    InstanceUrl,
    Queries,
    QuerySizes,
    Entities,
    HistoricalBaseline,
    CurrentExportRate,
    AccountName,
    UPNSuffix,
    CloudAppId
relevantTechniques:
- T1048
queryFrequency: 1d
description: Identifies users retrieving significantly more records from Dataverse than they have previously in the past 2 weeks.
customDetails: {}
severity: Low
entityMappings:
- fieldMappings:
  - identifier: Name
    columnName: AccountName
  - identifier: UPNSuffix
    columnName: UPNSuffix
  entityType: Account
- fieldMappings:
  - identifier: AppId
    columnName: CloudAppId
  - identifier: InstanceName
    columnName: InstanceUrl
  entityType: CloudApplication
triggerThreshold: 0
tactics:
- Exfiltration
requiredDataConnectors:
- dataTypes:
  - DataverseActivity
  connectorId: Dataverse
eventGroupingSettings:
  aggregationKind: AlertPerResult
queryPeriod: 14d
id: 08cb7ffc-59c6-4e7d-88e0-327371c9431b
triggerOperator: gt
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Business Applications/Analytic Rules/Dataverse - User bulk retrieval outside normal activity.yaml
query: |
  let baseline_time = 14d;
  let detection_time = 1d;
  DataverseActivity
  | where TimeGenerated between(ago(baseline_time) .. ago(detection_time - 1d))
  | where Message == "RetrieveMultiple"
  | extend numQueryCount = todouble(QueryResults)
  | extend QueryCount = iif(QueryResults contains ",", todouble(countof(tostring(QueryResults), ',') + 1), numQueryCount)
  | extend QueryCount = iif(isnotempty(QueryCount), QueryCount, double(1))
  | summarize sum(QueryCount) by UserId
  | extend HistoricalBaseline = sum_QueryCount
  | join kind=inner (
      DataverseActivity
      | where TimeGenerated > ago(detection_time)
      | where Message == "RetrieveMultiple"
      | extend numQueryCount = todouble(QueryResults)
      | extend QueryCount = iif(QueryResults contains ",", todouble(countof(tostring(QueryResults), ',') + 1), numQueryCount)
      | extend QueryCount = iif(isnotempty(QueryCount), QueryCount, double(1))
      | summarize sum(QueryCount) by UserId
      | extend CurrentExportRate = sum_QueryCount)
      on UserId
  | where CurrentExportRate > HistoricalBaseline
  | project UserId, HistoricalBaseline, CurrentExportRate
  | join kind=inner(
      DataverseActivity
      | where TimeGenerated > ago(detection_time)
      | where Message == "RetrieveMultiple"
      | extend numQueryCount = todouble(QueryResults)
      | extend QueryCount = iif(QueryResults contains ",", todouble(countof(tostring(QueryResults), ',') + 1), numQueryCount)
      | extend QueryCount = iif(isnotempty(QueryCount), QueryCount, double(1)))
      on UserId
  | summarize
      QuerySizes = make_set(QueryCount),
      MostRecentQuery = max(TimeGenerated),
      IPs = make_set(ClientIp),
      UserAgents = make_set(UserAgent),
      Entities = make_set(EntityName),
      Queries = make_set(Query)
      by UserId, InstanceUrl, HistoricalBaseline, CurrentExportRate
  | extend
      AccountName = tostring(split(UserId, '@')[0]),
      UPNSuffix = tostring(split(UserId, '@')[1]),
      CloudAppId = int(32780)
  | project
      MostRecentQuery,
      UserId,
      IPs,
      UserAgents,
      InstanceUrl,
      Queries,
      QuerySizes,
      Entities,
      HistoricalBaseline,
      CurrentExportRate,
      AccountName,
      UPNSuffix,
      CloudAppId  
alertDetailsOverride:
  alertDisplayNameFormat: Dataverse - Bulk record retrieval outside of normal activity
  alertDescriptionFormat: '{{UserId}} exported {{CurrentExportRate}} records, far beyond the historical baseline of {{{HistoricalBaseline}}.'
name: Dataverse - User bulk retrieval outside normal activity
version: 3.2.0
kind: Scheduled
status: Available