Adversaries may delete files to cover their tracks or exfiltrate data, indicating potential data manipulation or exfiltration. SOC teams should proactively hunt for unusual file deletion patterns to identify and mitigate potential data compromise in Azure Sentinel.
KQL Query
let relevantOperations = pack_array("FileDeleted", "FileRecycled", "FileDeletedFirstStageRecycleBin", "FileDeletedSecondStageRecycleBin", "FileVersionsAllMinorsRecycled", "FileVersionRecycled", "FileVersionsAllRecycled");
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));
//
let deleteEvents = // look for file deletion activity and scope it to risky users
CloudAppEvents
| where hasUsers
| where Timestamp between ((timeNow - timeWindow) .. (timeNow))
| where ApplicationId in (relevantAppIds)
| where isnotempty(AccountObjectId)
| where AccountObjectId in (riskyUsers)
| where ActionType in (relevantOperations)
| extend SessionId= tostring(RawEventData.AppAccessContext.AADSessionId)
| where isnotempty(SessionId)
| project AccountObjectId, AccountDisplayName, ApplicationId, SessionId, ActionType, Timestamp, ReportId
;
//
deleteEvents
| join kind=leftsemi riskyUsers on AccountObjectId, SessionId
| summarize Count=count() , (Timestamp, ReportId)=arg_min(Timestamp, ReportId) by AccountObjectId, AccountDisplayName, ApplicationId, ActionType, Time=bin(Timestamp, 5m)
// look for only those scoped users who have generated an increase in file deletion activity.
| summarize TotalCount= countif(Count > 50), (Timestamp, ReportId)=arg_min(Timestamp, ReportId) by AccountObjectId, AccountDisplayName, ApplicationId
| where TotalCount >= 3
| project AccountObjectId, AccountDisplayName, ApplicationId, TotalCount, ReportId, Timestamp
| extend NTDomain = tostring(split(AccountDisplayName,'\\',0)[0]), Name = tostring(split(AccountDisplayName,'\\',1)[0])
| extend Account_0_Name = Name
| extend Account_0_NTDomain = NTDomain
| extend Account_0_AadUserId = AccountObjectId
| extend CloudApplication_0_AppId = ApplicationId
id: 611ebbc2-c789-42ad-93e3-6dc02bfa5e3d
name: Unusual volume of file deletion by user.
description: |
This query looks for users performing file deletion activities. Spikes in file deletion observed from risky sign-in sessions are flagged here.
This applies to SharePoint and OneDrive users.
Audit event and Cloud application identifier references.
Reference - https://learn.microsoft.com/microsoft-365/compliance/audit-log-activities?view=o365-worldwide
Reference - https://learn.microsoft.com/azure/sentinel/entities-reference#cloud-application-identifiers
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- CloudAppEvents
- EntraIdSignInEvents
tactics:
- Impact
query: |
let relevantOperations = pack_array("FileDeleted", "FileRecycled", "FileDeletedFirstStageRecycleBin", "FileDeletedSecondStageRecycleBin", "FileVersionsAllMinorsRecycled", "FileVersionRecycled", "FileVersionsAllRecycled");
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));
//
let deleteEvents = // look for file deletion activity and scope it to risky users
CloudAppEvents
| where hasUsers
| where Timestamp between ((timeNow - timeWindow) .. (timeNow))
| where ApplicationId in (relevantAppIds)
| where isnotempty(AccountObjectId)
| where AccountObjectId in (riskyUsers)
| where ActionType in (relevantOperations)
| extend SessionId= tostring(RawEventData.AppAccessContext.AADSessionId)
| where isnotempty(SessionId)
| project AccountObjectId, AccountDisplayName, ApplicationId, SessionId, ActionType, Timestamp, ReportId
;
//
deleteEvents
| join kind=leftsemi riskyUsers on AccountObjectId, SessionId
| summarize Count=count() , (Timestamp, ReportId)=arg_min(Timestamp, ReportId) by AccountObjectId, AccountDisplayName, ApplicationId, ActionType, Time=bin(Timestamp, 5m)
// look for only those scoped users who have generated an increase in file deletion activity.
| summarize TotalCount= countif(Count > 50), (Timestamp, ReportId)=arg_min(Timestamp, ReportId) by AccountObjectId, AccountDisplayName, ApplicationId
| where TotalCount >= 3
| project AccountObjectId, AccountDisplayName, ApplicationId, TotalCount, ReportId, Timestamp
| extend NTDomain = tostring(split(AccountDisplayName,'\\',0)[0]), Name = tostring(split(AccountDisplayName,'\\',1)[0])
| Sentinel Table | Notes |
|---|---|
CloudAppEvents | Ensure this data connector is enabled |
Scenario: Scheduled Backup Job Execution
Description: A scheduled backup job (e.g., Veeam, Acronis, or Azure Backup) is running and deleting temporary files or logs as part of its cleanup process.
Filter/Exclusion: Exclude events where the file path matches known backup directories (e.g., C:\Backup\, D:\Temp\) or where the process name matches backup tools (e.g., VeeamBackup.exe, AcronisAgent.exe).
Scenario: User-Initiated File Cleanup
Description: A user is manually cleaning up old files (e.g., using Windows File Explorer, PowerShell, or third-party tools like CCleaner) as part of routine maintenance.
Filter/Exclusion: Exclude events where the user is a system admin or has elevated privileges, or where the file deletion is performed from known cleanup tools (e.g., cleanmgr.exe, CCleaner.exe).
Scenario: Log File Rotation or Purging
Description: System or application log files (e.g., IIS logs, Windows Event Logs, or application logs) are being purged as part of log rotation or retention policies.
Filter/Exclusion: Exclude events where the file path matches log directories (e.g., C:\Windows\System32\LogFiles\, C:\inetpub\logs\) or where the process is related to log management tools (e.g., logrotate.exe, SplunkForwarder.exe).
Scenario: User-Driven File Deletion for Compliance
Description: A user is deleting files as part of a compliance or legal review (e.g., using Microsoft Purview or third-party eDiscovery tools).
Filter/Exclusion: Exclude events where the user is a compliance officer or has access to eDiscovery tools (e.g