Home / Blog / Detection Engineering

Advanced Detection Engineering

How to Detect Backup and Recovery Tampering Before Ransomware Hits

Build detections for shadow copy deletion, backup catalog wipes and disabled Windows recovery, tune them per client and contain fast when they fire.

Before most ransomware encrypts anything, the operator makes sure you cannot easily recover: shadow copies deleted, backup catalogs wiped, Windows recovery switched off. These commands are short, noisy and usually run shortly before encryption starts, which makes them one of the last good chances to stop an attack. This guide is for detection engineers and incident responders building rules that work across many client estates, where the same command can be routine at one client and an emergency at the next.

TechniqueT1490 Inhibit System Recovery, often with T1489 Service Stop
Key telemetryProcess creation with command line, Application 524, System 7036
Response windowOften minutes, so containment must be automated
>

Scenario: At 23:47 on a Saturday, a rule fires in a client tenant: vssadmin delete shadows /all /quiet on APP-07, an application server at a logistics firm. The parent is cmd.exe, started under a service account the client uses for patch deployment. Four minutes later the same command runs on six more servers. The client's on call contact is not answering. Your runbook says isolate on confirmed ransomware precursors, but last month a backup agent at a different client ran vssadmin resize shadowstorage and tripped a similar rule. You need to know which situation this is, quickly.

Know the commands operators use

MITRE ATT&CK lists T1490 under the Impact tactic and records it for a long list of ransomware families, including WannaCry, REvil, Clop, RansomHub and BlackByte. In October 2025 MITRE also published a detection strategy for it, DET0329, which focuses on process chains that run native utilities with arguments to delete shadow copies, disable recovery or remove backup catalogs. In practice, operators reach for a small set of built in tools.

UtilityPattern to detectWhat it breaks
vssadmin.exedelete shadows, or resize shadowstorage with a tiny maximum sizeVolume shadow copies used for file and system restore
wmic.exeshadowcopy deleteVolume shadow copies, through WMI instead of vssadmin
powershell.exeWin32_ShadowCopy with a delete or remove cmdletVolume shadow copies, through CIM or WMI classes
wbadmin.exedelete catalog, delete systemstatebackupWindows Server Backup catalog and system state backups
bcdedit.exerecoveryenabled no, bootstatuspolicy ignoreallfailuresAutomatic repair and the Windows Recovery Environment at boot
reagentc.exe/disableThe Windows Recovery Environment
diskshadow.exeScript mode, /s, on a host that does not run backupsShadow copies, while avoiding rules that only watch vssadmin
i

Note: Shrinking shadow storage looks harmless but is not. When the maximum size is set below what existing copies use, Windows deletes copies to fit. Treat a resize to a very small value with the same suspicion as an explicit delete.

Confirm the telemetry exists in every client

Every rule in this article depends on command line visibility. A process name alone cannot tell routine backup administration from tampering. Before you deploy, check each client estate for these sources:

  • Security Event ID 4688 with "Include command line in process creation events" enabled by Group Policy, or Sysmon Event ID 1, or EDR process telemetry such as DeviceProcessEvents.
  • Application log Event ID 524 from the Microsoft-Windows-Backup provider, "The System Catalog has been deleted", on servers running Windows Server Backup.
  • System log Event ID 7036 from the Service Control Manager, which records services entering the stopped state.
  • Coverage on servers as well as workstations, because file servers and hypervisor management hosts are where recovery tampering hurts most.
!

Watch out: Many clients trim Windows log collection to save ingestion costs, and the Application and System logs are often the first to go. If those logs are filtered out, the 524 and 7036 signals below never reach your SIEM. Record the gap in the client's onboarding notes rather than assuming coverage.

Build the core detection

Write one rule that classifies each recovery tampering pattern and tells the analyst which one fired. A named pattern in the alert speeds up triage far more than a generic "suspicious command" title.

Microsoft Defender XDR

Microsoft Defender XDR advanced huntingKQL
DeviceProcessEvents
| where Timestamp > ago(1d)
| extend Cmd = tolower(ProcessCommandLine),
         Bin = tolower(coalesce(ProcessVersionInfoOriginalFileName, FileName))
| extend Pattern = case(
    Bin startswith "vssadmin" and Cmd contains "delete" and Cmd contains "shadows", "VSS shadow delete",
    Bin startswith "vssadmin" and Cmd contains "resize" and Cmd contains "shadowstorage", "VSS storage resize",
    Bin startswith "wmic" and Cmd contains "shadowcopy" and Cmd contains "delete", "WMIC shadow delete",
    Bin in ("powershell.exe", "pwsh.dll", "pwsh.exe") and Cmd contains "win32_shadowcopy"
        and (Cmd contains "delete" or Cmd contains "remove-"), "PowerShell shadow delete",
    Bin startswith "wbadmin" and Cmd contains "delete"
        and (Cmd contains "catalog" or Cmd contains "systemstatebackup" or Cmd contains "backup"), "WBAdmin backup delete",
    Bin startswith "bcdedit" and ((Cmd contains "recoveryenabled" and Cmd contains "no")
        or Cmd contains "ignoreallfailures"), "Boot recovery disabled",
    Bin startswith "reagentc" and Cmd contains "/disable", "WinRE disabled",
    Bin startswith "diskshadow" and Cmd contains "/s", "Diskshadow script mode",
    "")
| where isnotempty(Pattern)
| project Timestamp, DeviceName, Pattern, AccountName, FileName, ProcessCommandLine,
          InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessAccountName
| order by Timestamp desc

Using ProcessVersionInfoOriginalFileName before FileName means a copy of vssadmin.exe renamed to something innocent is still classified correctly, because the original file name in the version resource does not change when the file is renamed.

Splunk with Sysmon

Splunk, Sysmon Event ID 1SPL
index=sysmon EventCode=1
    (OriginalFileName="VSSADMIN.EXE" OR OriginalFileName="wmic.exe" OR OriginalFileName="wbadmin.exe"
     OR OriginalFileName="bcdedit.exe" OR OriginalFileName="REAgentC.exe" OR Image="*\\powershell.exe")
| eval cmd=lower(CommandLine)
| eval pattern=case(
    like(cmd, "%vssadmin%delete%shadows%"), "VSS shadow delete",
    like(cmd, "%vssadmin%resize%shadowstorage%"), "VSS storage resize",
    like(cmd, "%shadowcopy%delete%"), "WMIC shadow delete",
    like(cmd, "%win32_shadowcopy%") AND (like(cmd, "%delete%") OR like(cmd, "%remove-%")), "PowerShell shadow delete",
    like(cmd, "%wbadmin%delete%"), "WBAdmin backup delete",
    like(cmd, "%recoveryenabled%no%") OR like(cmd, "%ignoreallfailures%"), "Boot recovery disabled",
    like(cmd, "%reagentc%/disable%"), "WinRE disabled")
| where isnotnull(pattern)
| table _time host pattern User Image CommandLine ParentImage ParentCommandLine

Sigma for mixed client SIEMs

If your clients run different SIEMs, keep the logic in Sigma and convert it for each platform. This rule covers the four most common patterns. Add the rest as further selections.

Sigma, process creationYAML
title: Recovery Inhibition via Native Windows Utilities
id: 6f3c2a9e-4b1d-4e8a-9c7f-2d5b8e1a0c34
status: experimental
description: Detects deletion of shadow copies or backup catalogs, or disabling of boot recovery, using built in utilities.
references:
    - https://attack.mitre.org/techniques/T1490/
tags:
    - attack.impact
    - attack.t1490
logsource:
    category: process_creation
    product: windows
detection:
    selection_vssadmin:
        OriginalFileName: 'VSSADMIN.EXE'
        CommandLine|contains|all:
            - 'delete'
            - 'shadows'
    selection_wmic:
        OriginalFileName: 'wmic.exe'
        CommandLine|contains|all:
            - 'shadowcopy'
            - 'delete'
    selection_wbadmin:
        OriginalFileName: 'WBADMIN.EXE'
        CommandLine|contains|all:
            - 'delete'
            - 'catalog'
    selection_bcdedit:
        OriginalFileName: 'bcdedit.exe'
        CommandLine|contains|all:
            - 'recoveryenabled'
            - 'no'
    condition: 1 of selection_*
falsepositives:
    - Backup software or administrators maintaining shadow storage, confirmed by change records
level: high
+

Tip: Check the original file name values in your own telemetry before relying on them, because casing differs between binaries and some SIEM pipelines do not populate the field. If it is missing, fall back to Image|endswith and accept that renamed copies will slip through that leg of the rule.

Add the supporting signals

Recovery tampering rarely happens alone. Operators stop backup and database services so files are not locked, and they push the same commands to many hosts at once through remote execution or Group Policy. These supporting signals raise confidence and widen your scope.

Microsoft Sentinel, System Event ID 7036KQL
Event
| where TimeGenerated > ago(1d)
| where EventLog == "System" and Source == "Service Control Manager" and EventID == 7036
| where RenderedDescription has "stopped state"
| where RenderedDescription has_any ("Volume Shadow Copy", "Block Level Backup Engine", "Veeam", "SQL Server", "Backup")
| summarize Stops = count(), Services = make_set(RenderedDescription, 20),
    FirstStop = min(TimeGenerated), LastStop = max(TimeGenerated) by Computer
| order by Stops desc
Microsoft Defender XDR advanced huntingKQL
DeviceProcessEvents
| where Timestamp > ago(1d)
| extend Cmd = tolower(ProcessCommandLine)
| where (Cmd contains "shadows" and Cmd contains "delete")
    or (Cmd contains "shadowcopy" and Cmd contains "delete")
    or (Cmd contains "wbadmin" and Cmd contains "delete")
    or Cmd contains "recoveryenabled"
| summarize Hosts = dcount(DeviceName), HostList = make_set(DeviceName, 50),
    Commands = make_set(ProcessCommandLine, 10)
    by InitiatingProcessAccountName, bin(Timestamp, 15m)
| where Hosts >= 3
| order by Hosts desc

The second query is the one that would have settled the scenario. One account running shadow deletion on seven servers inside fifteen minutes is not a backup agent doing housekeeping.

Same command on many hosts

High
Indicator

Recovery tampering from one account on three or more hosts in a short window, often via a deployment account.

Response

Treat as active ransomware deployment. Isolate the hosts and disable the account straight away.

Backup catalog deleted

High
Indicator

Application Event ID 524 from Microsoft-Windows-Backup with no matching change record.

Response

Confirm offline or immutable backups are intact and protect the backup console credentials.

Backup services stopped

Med
Indicator

Several backup or database services entering the stopped state on one host outside maintenance windows.

Response

Correlate with process creation on the host and escalate if any tampering command is nearby.

Tune per client without blinding the rule

Some legitimate software does run these commands. Backup agents manage shadow storage, imaging tools touch boot configuration and administrators occasionally clean up old copies. The mistake is to exclude the utility, the host or the account. Exclude only the exact, approved combination.

Avoid

Broad exclusions

Excluding vssadmin.exe everywhere, or a whole server or service account. One stolen account then disables your best ransomware signal.

Exclude host BKP-01
Acceptable

Parent based

Allow a specific signed backup agent as the parent process on named hosts. Better, but an operator can still inject through that agent.

Parent is the backup agent on BKP-01
Recommended

Exact match per client

Host, parent path and the exact command the vendor documents, kept in a client watchlist with an owner and review date.

Resize to the agreed size only
Microsoft Sentinel, per client allow listKQL
let Allowed = _GetWatchlist('RecoveryToolAllowlist')
    | project DeviceName = tolower(tostring(DeviceName)),
              ParentPath = tolower(tostring(ParentPath)),
              ApprovedCommand = tolower(tostring(ApprovedCommand));
DeviceProcessEvents
| where TimeGenerated > ago(1h)
| where FileName in~ ("vssadmin.exe", "wmic.exe", "wbadmin.exe", "bcdedit.exe", "reagentc.exe")
| extend DeviceKey = tolower(DeviceName),
         ParentKey = tolower(InitiatingProcessFolderPath),
         CmdKey = tolower(ProcessCommandLine)
| join kind=leftanti Allowed
    on $left.DeviceKey == $right.DeviceName, $left.ParentKey == $right.ParentPath, $left.CmdKey == $right.ApprovedCommand
| project TimeGenerated, DeviceName, AccountName, ProcessCommandLine, InitiatingProcessFolderPath

Keep the watchlist small and review it with the client every quarter. When a backup product is replaced, its entries should go with it. Stale exceptions are exactly what an operator who has read your client's documentation will look for.

Respond in minutes and report to the client

When this rule fires for real, encryption may already be running on other hosts. Agree in advance with every client that a confirmed recovery tampering alert authorises automated containment, and put that agreement in the contract or the runbook, not in an email thread.

  1. L0
    AlertRule fires with the pattern name, host, account and parent process in the incident title.
    Automation
  2. L1
    ContainEDR isolates the host and the initiating account is disabled, under pre agreed client authority.
    Playbook
  3. L2
    ScopeRun the multi host query, check for service stops and find the deployment method.
    IR consultant
  4. L3
    RecoverConfirm offline backups are clean before restoring, and rebuild trust in backup credentials.
    Client and MSP
  • Collect the EDR timeline and process tree for each affected host before anyone reboots or reimages it.
  • Check the backup server and backup console sign ins, because operators often target those credentials directly.
  • Record every recovery feature that was disabled so the rebuild team can turn it back on, including boot configuration changes.
  • Note the exact times in UTC: first tampering command, containment and first encrypted file if there was one.

In the client report, lead with whether recovery is still possible, then how far the operator got and how they deployed. A sentence such as "shadow copies were deleted on seven servers, offline backups are intact and verified, encryption did not start" answers the questions the client's board will ask first. Then list the gaps, such as servers without command line logging, and the actions you need from them.

Key takeaways

  1. Recovery tampering with vssadmin, wmic, wbadmin, bcdedit and similar tools is one of the last reliable warnings before encryption.
  2. Command line visibility is essential, so confirm 4688 with command line, Sysmon or EDR telemetry in every client estate.
  3. Classify the pattern in the rule, use original file names to catch renamed binaries and keep portable logic in Sigma.
  4. Add Event ID 524, service stops and multi host bursts to raise confidence and widen scope.
  5. Tune with exact per client exceptions in a watchlist, never by excluding a utility, host or account.
  6. Agree automated containment with each client in advance, because the response window is often minutes.

Run the multi host query across every client tenant you manage today, then compare the core rule's last 30 days of results with each client's backup software. You will finish with a short, documented exception list per client and a rule you can trust to isolate a host at 23:47 on a Saturday.

Written by Chris, Lead IR Consultant, MSP

Keep going

More in Detection Engineering