← Back to SOC feed Coverage →

Unusual volume of file sharing with external user.

kql MEDIUM Azure-Sentinel
CloudAppEvents
huntingmicrosoftofficial
This rule was pulled from an open-source repository and enriched with AI. Validate in a test environment before deploying to production.
View original rule at Azure-Sentinel →
Retrieved: 2026-05-21T11:00:00Z · Confidence: medium

Hunt Hypothesis

Adversaries may be sharing sensitive files with external users to exfiltrate data or establish a foothold. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify potential data leakage or compromise early.

KQL Query

let usefulExtn= pack_array('csv', 'doc', 'docm', 'docx', 'dot', 'dotx', 'eml', 'pdf', 'pot', 'potm', 'potx', 'ppam', 'pps', 'ppsm', 'ppsx', 'ppt', 'pptm', 'pptx',
  'psd', 'pst', 'pub', 'ppk', 'rar', 'rtf', 'txt', 'vsd', 'vsdm', 'vsdx', 'vss', 'vssm', 'vst', 'vstm', 'vstx', 'xla', 'xlam', 'xll', 'xlm', 'xls', 'xlsm', 'xlsx', 'xlt',
  'xltm', 'xltx', 'xps', 'zip', 'xsl');
let sharingPerms= pack_array("AnonymousLinkCreated", "SharingInvitationCreated", "SharingSet");
let relevantAppIds = pack_array(int(20892), int(15600)); // App Ids for SharePoint and OneDrive
let timeWindow = 24h;
let timeNow = now();
//
let riskyUsers= // Look for users with risky sign-ins
  EntraIdSignInEvents    
  | where Timestamp between ((timeNow - timeWindow) .. (timeNow))
  | where isnotempty(AccountObjectId) and isnotempty(RequestId) // In EntraIdSignInEvents, the SessionId column has inaccurate data and instead the RequestId has the actual Session identifier
  | where ErrorCode == 0
  | where RiskLevelDuringSignIn >=80
  | project RiskLevelDuringSignIn, AccountObjectId, Timestamp, SessionId=RequestId
  ;
let hasUsers = isnotempty(toscalar(riskyUsers));
//
CloudAppEvents // look for file sharing activity and scope it to risky users
  | where hasUsers
  | where Timestamp between ((timeNow - timeWindow) .. (timeNow))
  | where ApplicationId in (relevantAppIds)
  | where AccountObjectId in (riskyUsers)
  | where ActionType in (sharingPerms)
  | extend SourceFileExtension = tostring(RawEventData.SourceFileExtension), SourceFileName=tostring(RawEventData.SourceFileName), TargetGroup=tostring(RawEventData.TargetUserOrGroupType)
  | where SourceFileExtension has_any (usefulExtn)
  | where TargetGroup == "Guest"
  //
  | summarize Count = countif(isnotempty( SourceFileName)), (Timestamp, ReportId)=arg_min(Timestamp, ReportId) ,FileNames = make_set(SourceFileName, 10) ,FileExt = make_set(SourceFileExtension, 10) by AccountObjectId, AccountDisplayName, ApplicationId, ActionType, Time = bin(Timestamp, 10m)
  | summarize TotalCount = countif(Count > 10) , (Timestamp, ReportId)=arg_min(Timestamp, ReportId) by AccountObjectId, AccountDisplayName, ApplicationId
  | where TotalCount > 1

Analytic Rule Definition

id: bafc1446-1cc4-4f6d-ad76-1250b8c3b60c
name: Unusual volume of file sharing with external user.
description: |
  This query looks for users sharing access to files with external users. 
  This applies to SharePoint and OneDrive users.
  Audit event and Cloud application identifier references.  
  Reference - https://learn.microsoft.com/microsoft-365/compliance/audit-log-sharing?view=o365-worldwide
  Reference - https://learn.microsoft.com/azure/sentinel/entities-reference#cloud-application-identifiers
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
  dataTypes:
  - CloudAppEvents
  - EntraIdSignInEvents
tactics:
- Exfiltration
query: |
  let usefulExtn= pack_array('csv', 'doc', 'docm', 'docx', 'dot', 'dotx', 'eml', 'pdf', 'pot', 'potm', 'potx', 'ppam', 'pps', 'ppsm', 'ppsx', 'ppt', 'pptm', 'pptx',
    'psd', 'pst', 'pub', 'ppk', 'rar', 'rtf', 'txt', 'vsd', 'vsdm', 'vsdx', 'vss', 'vssm', 'vst', 'vstm', 'vstx', 'xla', 'xlam', 'xll', 'xlm', 'xls', 'xlsm', 'xlsx', 'xlt',
    'xltm', 'xltx', 'xps', 'zip', 'xsl');
  let sharingPerms= pack_array("AnonymousLinkCreated", "SharingInvitationCreated", "SharingSet");
  let relevantAppIds = pack_array(int(20892), int(15600)); // App Ids for SharePoint and OneDrive
  let timeWindow = 24h;
  let timeNow = now();
  //
  let riskyUsers= // Look for users with risky sign-ins
    EntraIdSignInEvents    
    | where Timestamp between ((timeNow - timeWindow) .. (timeNow))
    | where isnotempty(AccountObjectId) and isnotempty(RequestId) // In EntraIdSignInEvents, the SessionId column has inaccurate data and instead the RequestId has the actual Session identifier
    | where ErrorCode == 0
    | where RiskLevelDuringSignIn >=80
    | project RiskLevelDuringSignIn, AccountObjectId, Timestamp, SessionId=RequestId
    ;
  let hasUsers = isnotempty(toscalar(riskyUsers));
  //
  CloudAppEvents // look for file sharing activity and scope it to risky users
    | where hasUsers
    | where Timestamp between ((timeNow - timeWindow) .. (timeNow))
    | where ApplicationId in (relevantAppIds)
    | where AccountObjectId in (riskyUsers)
    | where ActionType in (sharingPerms)
    | extend SourceFileExtension = tostring(RawEventData.SourceFileExtension), SourceFileName=tostring(RawEventData.SourceFileName), TargetGroup=tostring(RawEventData.TargetUserOrGroupType)
    | where SourceFileExtension has_any (usefulExtn)
    | where TargetGroup == "Guest"
    //
    | summarize Count = countif(isnotempty( SourceFileName)), (Timestamp, ReportId)=arg_min(Timestamp, ReportId) ,FileNames = make_set(SourceFileName, 10) ,FileExt = make_set(SourceFileExtension, 10) by AccountObjectId, AccountDisplayName, ApplicationId, ActionType, Time = bin(Timestamp, 10m)
    | summarize TotalCount = countif(Count > 10) , (Timestamp, ReportId)=arg_min(Timestamp, ReportId) by AccountObjectId, AccountDisplayName, ApplicationId
    | where TotalCount > 1
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: AadUserId

Required Data Sources

Sentinel TableNotes
CloudAppEventsEnsure this data connector is enabled

MITRE ATT&CK Context

References

False Positive Guidance

Original source: https://github.com/Azure/Azure-Sentinel/blob/main/Hunting Queries/Microsoft 365 Defender/Exfiltration/unusual-volume-of-file-sharing.yaml