witness

Detection as code

Detections that have to prove themselves.

Every rule here is checked on every commit: it must catch an attack recorded in a Windows or Linux lab VM and stay quiet on look-alike normal activity. Rules that pass are translated for Microsoft Sentinel, Defender XDR and Splunk.

10rules for Windows and Linux
11ATT&CK techniques
0proven in the lab
10awaiting lab capture
37/37normal events left alone
1

Write the rule

A Sigma rule, tagged with the ATT&CK technique it covers and the false positives it was tuned against.

2

Record the evidence

The attack is run with Atomic Red Team in an isolated lab VM and the Sysmon events it leaves are saved next to the rule.

3

Prove it in CI

GitHub Actions replays the evidence through the rule. A missed attack or a noisy match fails the build.

Coverage across ATT&CK tactics

ProvenAwaiting captureFailing

Reconnaissance

No rules yet

Resource Development

No rules yet

Initial Access

No rules yet

Privilege Escalation

T1548.001

Credential Access

T1003.001

Discovery

No rules yet

Lateral Movement

No rules yet

Collection

No rules yet

Command and Control

T1105

Exfiltration

No rules yet

Impact

T1490

Rules

Setuid or Setgid Bit Set With chmod Linux T1548.001 high Awaiting lab capture

Detects chmod adding the setuid or setgid bit, in symbolic (u+s, g+s, +s) or octal (4xxx, 2xxx, 6xxx) form. A setuid copy of a shell or interpreter is a classic way back to root. Everyday permission changes such as chmod +x or chmod 755 do not match.

Recorded attack it must catch

Not recorded yet. The rule only counts as proven once scripts/capture.ps1 has recorded the real attack in the lab and the rule fires on every recorded test.

Normal activity it must ignore

ResultScenarioCommand line
QuietMaking a script executablechmod +x deploy.sh
QuietOwner-only execute bit (u+x, not u+s)chmod u+x build.sh
QuietStandard 755 on an app scriptchmod 755 /opt/app/run.sh
QuietRecursive 0750 on a data folderchmod -R 0750 /srv/data
QuietConfig file to 644chmod 644 /etc/nginx/nginx.conf

Ready-to-run queries

Microsoft Sentinel (ASIM, KQL)
imProcessCreate
| where TargetProcessName endswith "/chmod" and ((TargetProcessCommandLine contains "u+s" or TargetProcessCommandLine contains "g+s" or TargetProcessCommandLine contains "ug+s" or TargetProcessCommandLine contains " +s " or TargetProcessCommandLine contains "a+s") or TargetProcessCommandLine matches regex "(^|/|\\s)chmod\\s+(-\\S+\\s+)*0?[246][0-7]{3}\\s")
Microsoft Defender XDR (KQL)
DeviceProcessEvents
| where FolderPath endswith "/chmod" and ((ProcessCommandLine contains "u+s" or ProcessCommandLine contains "g+s" or ProcessCommandLine contains "ug+s" or ProcessCommandLine contains " +s " or ProcessCommandLine contains "a+s") or ProcessCommandLine matches regex "(^|/|\\s)chmod\\s+(-\\S+\\s+)*0?[246][0-7]{3}\\s")
Splunk (Sysmon, SPL)
sourcetype="sysmon:linux" EventCode=1 Image="*/chmod"
| rex field=CommandLine "(?<CommandLineMatch>(^|/|\\s)chmod\\s+(-\\S+\\s+)*0?[246][0-7]{3}\\s)"
| eval CommandLineCondition=if(isnotnull(CommandLineMatch), "true", "false")
| search CommandLine IN ("*u+s*", "*g+s*", "*ug+s*", "* +s *", "*a+s*") OR CommandLineCondition="true"
Shell History File Deleted or Emptied Linux T1070.003 medium Awaiting lab capture

Detects rm, shred, truncate or ln being pointed at a shell history file. Wiping .bash_history or linking it to /dev/null is how intruders hide the commands they ran. Reading the file (cat, less, grep) is ignored, so analysts reviewing history stay quiet.

Recorded attack it must catch

Not recorded yet. The rule only counts as proven once scripts/capture.ps1 has recorded the real attack in the lab and the rule fires on every recorded test.

Normal activity it must ignore

ResultScenarioCommand line
QuietReading shell historycat /home/raghav/.bash_history
QuietSearching shell historygrep sudo /home/raghav/.bash_history
QuietDeleting an old log filerm /home/raghav/.cache/old.log
QuietEnabling an nginx site with a symlinkln -s /etc/nginx/sites-available/app /etc/nginx/sites-enabled/app

Ready-to-run queries

Microsoft Sentinel (ASIM, KQL)
imProcessCreate
| where (TargetProcessName endswith "/rm" or TargetProcessName endswith "/shred" or TargetProcessName endswith "/truncate" or TargetProcessName endswith "/ln") and (TargetProcessCommandLine contains ".bash_history" or TargetProcessCommandLine contains ".zsh_history" or TargetProcessCommandLine contains ".sh_history" or TargetProcessCommandLine contains ".history")
Microsoft Defender XDR (KQL)
DeviceProcessEvents
| where (FolderPath endswith "/rm" or FolderPath endswith "/shred" or FolderPath endswith "/truncate" or FolderPath endswith "/ln") and (ProcessCommandLine contains ".bash_history" or ProcessCommandLine contains ".zsh_history" or ProcessCommandLine contains ".sh_history" or ProcessCommandLine contains ".history")
Splunk (Sysmon, SPL)
sourcetype="sysmon:linux" EventCode=1 Image IN ("*/rm", "*/shred", "*/truncate", "*/ln") CommandLine IN ("*.bash_history*", "*.zsh_history*", "*.sh_history*", "*.history*")
Crontab Installed From a Temporary Folder Linux T1053.003 medium Awaiting lab capture

Detects crontab loading a whole new table from a file in /tmp, /var/tmp or /dev/shm. Malware writes its schedule to a world-writable folder and installs it in one step for persistence. Editing with crontab -e or listing with -l never names such a file.

Recorded attack it must catch

Not recorded yet. The rule only counts as proven once scripts/capture.ps1 has recorded the real attack in the lab and the rule fires on every recorded test.

Normal activity it must ignore

ResultScenarioCommand line
QuietListing the crontabcrontab -l
QuietEditing the crontabcrontab -e
QuietInstalling a crontab from a file in the home foldercrontab /home/raghav/backup.cron

Ready-to-run queries

Microsoft Sentinel (ASIM, KQL)
imProcessCreate
| where TargetProcessName endswith "/crontab" and (TargetProcessCommandLine contains " /tmp/" or TargetProcessCommandLine contains " /var/tmp/" or TargetProcessCommandLine contains " /dev/shm/")
Microsoft Defender XDR (KQL)
DeviceProcessEvents
| where FolderPath endswith "/crontab" and (ProcessCommandLine contains " /tmp/" or ProcessCommandLine contains " /var/tmp/" or ProcessCommandLine contains " /dev/shm/")
Splunk (Sysmon, SPL)
sourcetype="sysmon:linux" EventCode=1 Image="*/crontab" CommandLine IN ("* /tmp/*", "* /var/tmp/*", "* /dev/shm/*")
Interactive Shell Redirected Over /dev/tcp Linux T1059.004 high Awaiting lab capture

Detects a command line that opens a bash /dev/tcp or /dev/udp socket and redirects the shell's input or output through it, the shape of a reverse shell. Opening /dev/tcp on its own is a common port check in health scripts, so the rule also requires a file descriptor redirection (>&, <&) before it fires.

Recorded attack it must catch

Not recorded yet. The rule only counts as proven once scripts/capture.ps1 has recorded the real attack in the lab and the rule fires on every recorded test.

Normal activity it must ignore

ResultScenarioCommand line
QuietHealth check opening /dev/tcp without redirecting the shellbash -c "timeout 1 bash -c '</dev/tcp/db.lab.local/5432' && echo open"
QuietScript merging stderr into stdout (>& without a socket)bash -c "pg_isready -h db.lab.local 2>&1"
QuietPort check with netcatnc -zv db.lab.local 5432

Ready-to-run queries

Microsoft Sentinel (ASIM, KQL)
imProcessCreate
| where (TargetProcessCommandLine contains "/dev/tcp/" or TargetProcessCommandLine contains "/dev/udp/") and (TargetProcessCommandLine contains ">&" or TargetProcessCommandLine contains "<&")
Microsoft Defender XDR (KQL)
DeviceProcessEvents
| where (ProcessCommandLine contains "/dev/tcp/" or ProcessCommandLine contains "/dev/udp/") and (ProcessCommandLine contains ">&" or ProcessCommandLine contains "<&")
Splunk (Sysmon, SPL)
sourcetype="sysmon:linux" EventCode=1 CommandLine IN ("*/dev/tcp/*", "*/dev/udp/*") CommandLine IN ("*>&*", "*<&*")
SSH authorized_keys Written From the Command Line Linux T1098.004 medium Awaiting lab capture

Detects a command that appends to, copies over or edits an authorized_keys file in place. Adding a key there gives an intruder a quiet way back in that survives password changes. Reading the file or fixing its permissions does not match.

Recorded attack it must catch

Not recorded yet. The rule only counts as proven once scripts/capture.ps1 has recorded the real attack in the lab and the rule fires on every recorded test.

Normal activity it must ignore

ResultScenarioCommand line
QuietReading authorized_keyscat /home/raghav/.ssh/authorized_keys
QuietFixing authorized_keys permissionschmod 600 /home/raghav/.ssh/authorized_keys
QuietListing key fingerprintsssh-keygen -lf /home/raghav/.ssh/authorized_keys
QuietCounting ed25519 keysgrep -c ssh-ed25519 /home/raghav/.ssh/authorized_keys

Ready-to-run queries

Microsoft Sentinel (ASIM, KQL)
imProcessCreate
| where TargetProcessCommandLine contains "authorized_keys" and ((TargetProcessCommandLine contains ">>" or TargetProcessCommandLine contains "> " or TargetProcessCommandLine contains "tee " or TargetProcessCommandLine contains "sed -i") or (TargetProcessName endswith "/cp" or TargetProcessName endswith "/mv" or TargetProcessName endswith "/install"))
Microsoft Defender XDR (KQL)
DeviceProcessEvents
| where ProcessCommandLine contains "authorized_keys" and ((ProcessCommandLine contains ">>" or ProcessCommandLine contains "> " or ProcessCommandLine contains "tee " or ProcessCommandLine contains "sed -i") or (FolderPath endswith "/cp" or FolderPath endswith "/mv" or FolderPath endswith "/install"))
Splunk (Sysmon, SPL)
sourcetype="sysmon:linux" EventCode=1 CommandLine="*authorized_keys*" CommandLine IN ("*>>*", "*> *", "*tee *", "*sed -i*") OR Image IN ("*/cp", "*/mv", "*/install")
File Download With certutil Windows T1105 high Awaiting lab capture

Detects certutil.exe fetching a remote URL with -urlcache or -verifyctl. certutil is signed by Microsoft and present on every Windows host, so it is a favourite way to pull a second stage past application allow-listing. Requiring a URL scheme keeps routine cache maintenance such as "certutil -urlcache * delete" quiet.

Recorded attack it must catch

Not recorded yet. The rule only counts as proven once scripts/capture.ps1 has recorded the real attack in the lab and the rule fires on every recorded test.

Normal activity it must ignore

ResultScenarioCommand line
QuietChecking a download's SHA-256 hashcertutil.exe -hashfile C:\Users\analyst\Downloads\setup.exe SHA256
QuietClearing the URL cache (cache flag, but no URL)certutil.exe -urlcache * delete
QuietVerifying a certificate filecertutil.exe -verify C:\certs\root.cer

Ready-to-run queries

Microsoft Sentinel (ASIM, KQL)
imProcessCreate
| where (TargetProcessName endswith "\\certutil.exe" or TargetProcessFileOriginalName =~ "CertUtil.exe") and (TargetProcessCommandLine contains "-urlcache" or TargetProcessCommandLine contains "/urlcache" or TargetProcessCommandLine contains "–urlcache" or TargetProcessCommandLine contains "—urlcache" or TargetProcessCommandLine contains "―urlcache" or TargetProcessCommandLine contains "-verifyctl" or TargetProcessCommandLine contains "/verifyctl" or TargetProcessCommandLine contains "–verifyctl" or TargetProcessCommandLine contains "—verifyctl" or TargetProcessCommandLine contains "―verifyctl") and (TargetProcessCommandLine contains "http://" or TargetProcessCommandLine contains "https://" or TargetProcessCommandLine contains "ftp://")
Microsoft Defender XDR (KQL)
DeviceProcessEvents
| where (FolderPath endswith "\\certutil.exe" or ProcessVersionInfoOriginalFileName =~ "CertUtil.exe") and (ProcessCommandLine contains "-urlcache" or ProcessCommandLine contains "/urlcache" or ProcessCommandLine contains "–urlcache" or ProcessCommandLine contains "—urlcache" or ProcessCommandLine contains "―urlcache" or ProcessCommandLine contains "-verifyctl" or ProcessCommandLine contains "/verifyctl" or ProcessCommandLine contains "–verifyctl" or ProcessCommandLine contains "—verifyctl" or ProcessCommandLine contains "―verifyctl") and (ProcessCommandLine contains "http://" or ProcessCommandLine contains "https://" or ProcessCommandLine contains "ftp://")
Splunk (Sysmon, SPL)
source="WinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1 Image="*\\certutil.exe" OR OriginalFileName="CertUtil.exe" CommandLine="*-urlcache*" OR CommandLine="*/urlcache*" OR CommandLine="*–urlcache*" OR CommandLine="*—urlcache*" OR CommandLine="*―urlcache*" OR CommandLine="*-verifyctl*" OR CommandLine="*/verifyctl*" OR CommandLine="*–verifyctl*" OR CommandLine="*—verifyctl*" OR CommandLine="*―verifyctl*" CommandLine IN ("*http://*", "*https://*", "*ftp://*")
LSASS Memory Dump via comsvcs.dll MiniDump Windows T1003.001 high Awaiting lab capture

Detects rundll32 calling the MiniDump export of comsvcs.dll, a built-in way to dump LSASS memory without bringing any tools. Attackers often call the export by its ordinal (#24) to dodge string matches, so both forms are covered. The OriginalFileName branch still fires when rundll32.exe has been copied and renamed.

Recorded attack it must catch

Not recorded yet. The rule only counts as proven once scripts/capture.ps1 has recorded the real attack in the lab and the rule fires on every recorded test.

Normal activity it must ignore

ResultScenarioCommand line
QuietOpening Display settings from Control Panelrundll32.exe shell32.dll,Control_RunDLL desk.cpl
QuietOpening the printer install wizardrundll32.exe printui.dll,PrintUIEntry /il
QuietClearing Internet Explorer browsing datarundll32.exe inetcpl.cpl,ClearMyTracksByProcess 8

Ready-to-run queries

Microsoft Sentinel (ASIM, KQL)
imProcessCreate
| where (TargetProcessName endswith "\\rundll32.exe" or TargetProcessFileOriginalName =~ "RUNDLL32.EXE") and TargetProcessCommandLine contains "comsvcs" and (TargetProcessCommandLine contains "minidump" or TargetProcessCommandLine contains "#24" or TargetProcessCommandLine contains "#+24")
Microsoft Defender XDR (KQL)
DeviceProcessEvents
| where (FolderPath endswith "\\rundll32.exe" or ProcessVersionInfoOriginalFileName =~ "RUNDLL32.EXE") and ProcessCommandLine contains "comsvcs" and (ProcessCommandLine contains "minidump" or ProcessCommandLine contains "#24" or ProcessCommandLine contains "#+24")
Splunk (Sysmon, SPL)
source="WinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1 Image="*\\rundll32.exe" OR OriginalFileName="RUNDLL32.EXE" CommandLine="*comsvcs*" CommandLine IN ("*minidump*", "*#24*", "*#+24*")
PowerShell Launched With an Encoded Command Windows T1059.001 T1027 medium Awaiting lab capture

Detects powershell.exe or pwsh.exe started with -EncodedCommand or one of its short forms. Encoding hides the real script from command-line logging, which is why loaders and C2 stagers use it. The flag list deliberately leaves out "-enco": it also matches "-Encoding" inside ordinary -Command scripts and was the main source of noise.

Recorded attack it must catch

Not recorded yet. The rule only counts as proven once scripts/capture.ps1 has recorded the real attack in the lab and the rule fires on every recorded test.

Normal activity it must ignore

ResultScenarioCommand line
QuietRunning a script file with a relaxed execution policypowershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\Scripts\backup.ps1
QuietRe-encoding a text file: '-Encoding' must not be read as '-EncodedCommand'powershell.exe -NoProfile -Command "Get-Content .\in.txt | Out-File .\out.txt -Encoding utf8"
QuietListing servicespowershell.exe -Command Get-Service
QuietSCCM client running an encoded inventory command (filtered by parent)powershell.exe -NoLogo -NonInteractive -EncodedCommand RwBlAHQALQBEAGEAdABlAA==

Ready-to-run queries

Microsoft Sentinel (ASIM, KQL)
imProcessCreate
| where (((TargetProcessName endswith "\\powershell.exe" or TargetProcessName endswith "\\pwsh.exe") or (TargetProcessFileOriginalName in~ ("PowerShell.EXE", "pwsh.dll"))) and (TargetProcessCommandLine contains " -e " or TargetProcessCommandLine contains " /e " or TargetProcessCommandLine contains " –e " or TargetProcessCommandLine contains " —e " or TargetProcessCommandLine contains " ―e " or TargetProcessCommandLine contains " -ec " or TargetProcessCommandLine contains " /ec " or TargetProcessCommandLine contains " –ec " or TargetProcessCommandLine contains " —ec " or TargetProcessCommandLine contains " ―ec " or TargetProcessCommandLine contains " -en " or TargetProcessCommandLine contains " /en " or TargetProcessCommandLine contains " –en " or TargetProcessCommandLine contains " —en " or TargetProcessCommandLine contains " ―en " or TargetProcessCommandLine contains " -enc " or TargetProcessCommandLine contains " /enc " or TargetProcessCommandLine contains " –enc " or TargetProcessCommandLine contains " —enc " or TargetProcessCommandLine contains " ―enc " or TargetProcessCommandLine contains " -encodedcommand " or TargetProcessCommandLine contains " /encodedcommand " or TargetProcessCommandLine contains " –encodedcommand " or TargetProcessCommandLine contains " —encodedcommand " or TargetProcessCommandLine contains " ―encodedcommand ")) and (not((ParentProcessName startswith "C:\\Windows\\CCM\\" or ActingProcessName startswith "C:\\Windows\\CCM\\")))
Microsoft Defender XDR (KQL)
DeviceProcessEvents
| where (((FolderPath endswith "\\powershell.exe" or FolderPath endswith "\\pwsh.exe") or (ProcessVersionInfoOriginalFileName in~ ("PowerShell.EXE", "pwsh.dll"))) and (ProcessCommandLine contains " -e " or ProcessCommandLine contains " /e " or ProcessCommandLine contains " –e " or ProcessCommandLine contains " —e " or ProcessCommandLine contains " ―e " or ProcessCommandLine contains " -ec " or ProcessCommandLine contains " /ec " or ProcessCommandLine contains " –ec " or ProcessCommandLine contains " —ec " or ProcessCommandLine contains " ―ec " or ProcessCommandLine contains " -en " or ProcessCommandLine contains " /en " or ProcessCommandLine contains " –en " or ProcessCommandLine contains " —en " or ProcessCommandLine contains " ―en " or ProcessCommandLine contains " -enc " or ProcessCommandLine contains " /enc " or ProcessCommandLine contains " –enc " or ProcessCommandLine contains " —enc " or ProcessCommandLine contains " ―enc " or ProcessCommandLine contains " -encodedcommand " or ProcessCommandLine contains " /encodedcommand " or ProcessCommandLine contains " –encodedcommand " or ProcessCommandLine contains " —encodedcommand " or ProcessCommandLine contains " ―encodedcommand ")) and (not(InitiatingProcessFolderPath startswith "C:\\Windows\\CCM\\"))
Splunk (Sysmon, SPL)
source="WinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1 Image IN ("*\\powershell.exe", "*\\pwsh.exe") OR OriginalFileName IN ("PowerShell.EXE", "pwsh.dll") CommandLine="* -e *" OR CommandLine="* /e *" OR CommandLine="* –e *" OR CommandLine="* —e *" OR CommandLine="* ―e *" OR CommandLine="* -ec *" OR CommandLine="* /ec *" OR CommandLine="* –ec *" OR CommandLine="* —ec *" OR CommandLine="* ―ec *" OR CommandLine="* -en *" OR CommandLine="* /en *" OR CommandLine="* –en *" OR CommandLine="* —en *" OR CommandLine="* ―en *" OR CommandLine="* -enc *" OR CommandLine="* /enc *" OR CommandLine="* –enc *" OR CommandLine="* —enc *" OR CommandLine="* ―enc *" OR CommandLine="* -encodedcommand *" OR CommandLine="* /encodedcommand *" OR CommandLine="* –encodedcommand *" OR CommandLine="* —encodedcommand *" OR CommandLine="* ―encodedcommand *" NOT ParentImage="C:\\Windows\\CCM\\*"
Scheduled Task Created to Run From a User-Writable Folder Windows T1053.005 medium Awaiting lab capture

Detects schtasks /create where the task runs something out of Temp, Public or the roaming profile. Malware drops its payload where any user can write and then adds a task for persistence. AppData\Local as a whole is left out on purpose: OneDrive, Teams and other per-user updaters legitimately schedule tasks from there.

Recorded attack it must catch

Not recorded yet. The rule only counts as proven once scripts/capture.ps1 has recorded the real attack in the lab and the rule fires on every recorded test.

Normal activity it must ignore

ResultScenarioCommand line
QuietOneDrive scheduling its per-user updater under AppData\Localschtasks.exe /create /tn "OneDrive Standalone Update Task" /tr "C:\Users\analyst\AppData\Local\Microsoft\OneDrive\OneDriveStandaloneUpdater.exe" /sc daily
QuietAdmin scheduling a backup from Program Filesschtasks.exe /create /tn "Nightly Backup" /tr "C:\Program Files\Backup\backup.exe" /sc daily /st 02:00
QuietListing scheduled tasksschtasks.exe /query /fo LIST

Ready-to-run queries

Microsoft Sentinel (ASIM, KQL)
imProcessCreate
| where (TargetProcessName endswith "\\schtasks.exe" or TargetProcessFileOriginalName =~ "schtasks.exe") and (TargetProcessCommandLine contains "-create" or TargetProcessCommandLine contains "/create" or TargetProcessCommandLine contains "–create" or TargetProcessCommandLine contains "—create" or TargetProcessCommandLine contains "―create") and (TargetProcessCommandLine contains "\\AppData\\Local\\Temp\\" or TargetProcessCommandLine contains "\\AppData\\Roaming\\" or TargetProcessCommandLine contains "\\Users\\Public\\" or TargetProcessCommandLine contains "\\Windows\\Temp\\" or TargetProcessCommandLine contains "%TEMP%" or TargetProcessCommandLine contains "%TMP%" or TargetProcessCommandLine contains "%APPDATA%" or TargetProcessCommandLine contains "%PUBLIC%")
Microsoft Defender XDR (KQL)
DeviceProcessEvents
| where (FolderPath endswith "\\schtasks.exe" or ProcessVersionInfoOriginalFileName =~ "schtasks.exe") and (ProcessCommandLine contains "-create" or ProcessCommandLine contains "/create" or ProcessCommandLine contains "–create" or ProcessCommandLine contains "—create" or ProcessCommandLine contains "―create") and (ProcessCommandLine contains "\\AppData\\Local\\Temp\\" or ProcessCommandLine contains "\\AppData\\Roaming\\" or ProcessCommandLine contains "\\Users\\Public\\" or ProcessCommandLine contains "\\Windows\\Temp\\" or ProcessCommandLine contains "%TEMP%" or ProcessCommandLine contains "%TMP%" or ProcessCommandLine contains "%APPDATA%" or ProcessCommandLine contains "%PUBLIC%")
Splunk (Sysmon, SPL)
source="WinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1 Image="*\\schtasks.exe" OR OriginalFileName="schtasks.exe" CommandLine="*-create*" OR CommandLine="*/create*" OR CommandLine="*–create*" OR CommandLine="*—create*" OR CommandLine="*―create*" CommandLine IN ("*\\AppData\\Local\\Temp\\*", "*\\AppData\\Roaming\\*", "*\\Users\\Public\\*", "*\\Windows\\Temp\\*", "*%TEMP%*", "*%TMP%*", "*%APPDATA%*", "*%PUBLIC%*")
Shadow Copies or Backup Catalog Deleted Windows T1490 high Awaiting lab capture

Detects the commands ransomware runs just before encrypting, to stop the victim rolling back: deleting Volume Shadow Copies with vssadmin, wmic or PowerShell, deleting the Windows Backup catalog, and turning off boot recovery with bcdedit. Read-only commands such as "vssadmin list shadows" or "bcdedit /enum" do not match.

Recorded attack it must catch

Not recorded yet. The rule only counts as proven once scripts/capture.ps1 has recorded the real attack in the lab and the rule fires on every recorded test.

Normal activity it must ignore

ResultScenarioCommand line
QuietListing shadow copiesvssadmin.exe list shadows
QuietListing shadow copies with wmicwmic.exe shadowcopy list brief
QuietShowing boot configurationbcdedit.exe /enum
QuietListing backup versionswbadmin.exe get versions
QuietQuerying shadow copies from PowerShellpowershell.exe -Command Get-CimInstance Win32_ShadowCopy

Ready-to-run queries

Microsoft Sentinel (ASIM, KQL)
imProcessCreate
| where (TargetProcessName endswith "\\vssadmin.exe" and (TargetProcessCommandLine contains "delete" and TargetProcessCommandLine contains "shadows")) or (TargetProcessName endswith "\\wmic.exe" and (TargetProcessCommandLine contains "shadowcopy" and TargetProcessCommandLine contains "delete")) or ((TargetProcessName endswith "\\powershell.exe" or TargetProcessName endswith "\\pwsh.exe") and (TargetProcessCommandLine contains "Win32_ShadowCopy" and TargetProcessCommandLine contains "Delete")) or (TargetProcessName endswith "\\wbadmin.exe" and (TargetProcessCommandLine contains "delete" and TargetProcessCommandLine contains "catalog")) or (TargetProcessName endswith "\\bcdedit.exe" and (TargetProcessCommandLine contains "recoveryenabled no" or TargetProcessCommandLine contains "bootstatuspolicy ignoreallfailures"))
Microsoft Defender XDR (KQL)
DeviceProcessEvents
| where (FolderPath endswith "\\vssadmin.exe" and (ProcessCommandLine contains "delete" and ProcessCommandLine contains "shadows")) or (FolderPath endswith "\\wmic.exe" and (ProcessCommandLine contains "shadowcopy" and ProcessCommandLine contains "delete")) or ((FolderPath endswith "\\powershell.exe" or FolderPath endswith "\\pwsh.exe") and (ProcessCommandLine contains "Win32_ShadowCopy" and ProcessCommandLine contains "Delete")) or (FolderPath endswith "\\wbadmin.exe" and (ProcessCommandLine contains "delete" and ProcessCommandLine contains "catalog")) or (FolderPath endswith "\\bcdedit.exe" and (ProcessCommandLine contains "recoveryenabled no" or ProcessCommandLine contains "bootstatuspolicy ignoreallfailures"))
Splunk (Sysmon, SPL)
source="WinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1 (Image="*\\vssadmin.exe" CommandLine="*delete*" CommandLine="*shadows*") OR (Image="*\\wmic.exe" CommandLine="*shadowcopy*" CommandLine="*delete*") OR (Image IN ("*\\powershell.exe", "*\\pwsh.exe") CommandLine="*Win32_ShadowCopy*" CommandLine="*Delete*") OR (Image="*\\wbadmin.exe" CommandLine="*delete*" CommandLine="*catalog*") OR (Image="*\\bcdedit.exe" CommandLine IN ("*recoveryenabled no*", "*bootstatuspolicy ignoreallfailures*"))