Detection rules › Kusto

Dataverse - Mass download from SharePoint document management

Status
available
Severity
low
Time window
14d
Group by
ClientIP, InstanceUrl, SharePointUrl, Site_Url, UserId
Source
github.com/Azure/Azure-Sentinel

Identifies mass download (in the last hour) of files from SharePoint sites configured for document management in Dynamics 365. This analytics rule utilizes the MSBizApps-Configuration watchlist to identify SharePoint sites used for Document Management.

MITRE ATT&CK coverage

TacticTechniques
ExfiltrationT1567 Exfiltration Over Web Service

Event coverage

Rules detecting the same action

Other rules on this platform that filter on the same API call or operation.

Rule body kusto

id: 95e02f1b-5886-4043-8f0e-a42e6e23330f
kind: Scheduled
name: Dataverse - Mass download from SharePoint document management
description: Identifies mass download (in the last hour) of files from SharePoint
  sites configured for document management in Dynamics 365. This analytics rule utilizes
  the MSBizApps-Configuration watchlist to identify SharePoint sites used for Document
  Management.
severity: Low
status: Available
requiredDataConnectors:
  - connectorId: Office365
    dataTypes:
      - OfficeActivity (SharePoint)
queryFrequency: 1h
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Exfiltration
relevantTechniques:
  - T1567
query: |
  // Set threshold for number of downloaded files
  let detection_threshold = 10000;
  let query_frequency = 1h;
  DataverseSharePointSites
  | join kind=inner (
      OfficeActivity
      | where TimeGenerated >= ago(query_frequency)
      | where OfficeWorkload == "SharePoint" and Operation == "FileDownloaded")
      on $left.SharePointUrl == $right.Site_Url
  | summarize FileDownloadCount = count() by UserId, SharePointUrl, InstanceUrl, ClientIP
  | where FileDownloadCount > detection_threshold
  | extend
      CloudAppId = int(32780),
      SharePointId = int(20892),
      AccountName = tostring(split(UserId, '@')[0]),
      UPNSuffix = tostring(split(UserId, '@')[1])
  | project
      UserId,
      ClientIP,
      FileDownloadCount,
      SharePointUrl,
      InstanceUrl,
      CloudAppId,
      SharePointId,
      AccountName,
      UPNSuffix
eventGroupingSettings:
  aggregationKind: SingleAlert
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: AccountName
      - identifier: UPNSuffix
        columnName: UPNSuffix
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: ClientIP
  - entityType: CloudApplication
    fieldMappings:
      - identifier: AppId
        columnName: CloudAppId
      - identifier: InstanceName
        columnName: InstanceUrl
  - entityType: CloudApplication
    fieldMappings:
      - identifier: AppId
        columnName: SharePointId
      - identifier: InstanceName
        columnName: SharePointUrl
alertDetailsOverride:
  alertDisplayNameFormat: 'Dataverse - Mass download detected from document management
    in {{{InstanceUrl}} '
  alertDescriptionFormat: '{{{FileDownloadCount}} files were downloaded from {{SharePointUrl}}  by
    {{{UserId}}.'
version: 3.2.0

Stages and Predicates

Parameters

let detection_threshold = 10000;
let query_frequency = 1h;

Stage 1: source

DataverseSharePointSites

Stage 2: join

| join kind=inner (
    OfficeActivity
    | where TimeGenerated >= ago(query_frequency)
    | where OfficeWorkload == "SharePoint" and Operation == "FileDownloaded")
    on $left.SharePointUrl == $right.Site_Url

Stage 3: summarize

| summarize FileDownloadCount = count() by UserId, SharePointUrl, InstanceUrl, ClientIP
Threshold
gt 10000

Stage 4: where

| where FileDownloadCount > detection_threshold

Stage 5: extend

| extend
    CloudAppId = int(32780),
    SharePointId = int(20892),
    AccountName = tostring(split(UserId, '@')[0]),
    UPNSuffix = tostring(split(UserId, '@')[1])

Stage 6: project

| project
    UserId,
    ClientIP,
    FileDownloadCount,
    SharePointUrl,
    InstanceUrl,
    CloudAppId,
    SharePointId,
    AccountName,
    UPNSuffix

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
FileDownloadCountgt
  • 10000 transforms: cased
OfficeWorkloadeq
  • SharePoint transforms: cased
Operationeq
  • FileDownloaded transforms: cased

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

FieldSource
AccountNameproject
ClientIPproject
CloudAppIdproject
FileDownloadCountproject
InstanceUrlproject
SharePointIdproject
SharePointUrlproject
UPNSuffixproject
UserIdproject