查寻勒索软件

适用于:

  • Microsoft Defender XDR

勒索软件从影响个人计算机用户的简单商品恶意软件迅速演变为严重影响行业和政府机构的企业威胁。 虽然 Microsoft Defender XDR 提供了许多检测和阻止勒索软件和相关入侵活动的功能,但对入侵迹象执行主动检查有助于保护网络。

阅读有关人为操作的勒索软件的信息

借助Microsoft Defender XDR中的高级搜寻,可以创建查询来查找与勒索软件活动关联的单个项目。 还可以运行更复杂的查询,这些查询可以查找活动迹象并权衡这些迹象,以查找需要立即关注的设备。

勒索软件活动的迹象

Microsoft 安全研究人员在由复杂的入侵者发起的许多勒索软件活动中发现了各种常见但微妙的项目。 这些迹象主要涉及使用系统工具来准备加密、阻止检测和清除法医证据。

勒索软件活动 常用工具 Intent
停止进程 taskkill.exenet stop 确保针对加密的文件不会被各种应用程序锁定。
关闭服务 sc.exe - 确保针对加密的文件不会被各种应用程序锁定。
- 防止安全软件破坏加密和其他勒索软件活动。
- 停止备份软件创建可恢复的副本。
删除日志和文件 cipher.exewevtutilfsutil.exe 删除法医证据。
删除卷影副本 vsadmin.exewmic.exe 删除可用于恢复加密文件的驱动器卷影副本。
删除和停止备份 wbadmin.exe 删除现有备份并停止计划的备份任务,从而阻止加密后恢复。
修改启动设置 bcdedit.exe 在启动失败后关闭由加密过程引起的警告和自动修复。
关闭恢复工具 schtasks.exeregedit.exe 关闭系统还原和其他系统恢复选项。

检查勒索软件活动的个别迹象

许多构成勒索软件行为的活动(包括上一部分所述的活动)可能是良性的。 使用以下查询查找勒索软件时,请运行多个查询来检查同一设备是否表现出各种可能的勒索软件活动迹象。

使用 taskkill.exe 停止多个进程

此查询检查是否尝试使用 taskkill.exe 实用工具停止至少 10 个单独的进程。 运行查询

// Find attempts to stop processes using taskkill.exe
DeviceProcessEvents
| where Timestamp > ago(1d)
| where FileName =~ "taskkill.exe" 
| summarize taskKillCount = dcount(ProcessCommandLine), TaskKillList = make_set(ProcessCommandLine) by DeviceId, bin(Timestamp, 2m)
| where taskKillCount > 10

使用 net stop 停止进程

此查询检查是否尝试使用 net stop 命令停止至少 10 个单独的进程。 运行查询

// Find attempts to stop processes using net stop
DeviceProcessEvents
| where Timestamp > ago(1d)
| where FileName =~ "net.exe" and ProcessCommandLine has "stop"
| summarize netStopCount = dcount(ProcessCommandLine), NetStopList = make_set(ProcessCommandLine) by DeviceId, bin(Timestamp, 2m)
| where netStopCount > 10

使用 cipher.exe 删除多个驱动器上的数据

此查询检查是否尝试使用 cipher.exe删除多个驱动器上的数据。 此活动通常由勒索软件执行,以防止加密后恢复数据。 运行查询

// Look for cipher.exe deleting data from multiple drives
DeviceProcessEvents
| where Timestamp > ago(1d)
| where FileName =~ "cipher.exe" 
// cipher.exe /w flag used for deleting data 
| where ProcessCommandLine has "/w" 
| summarize CipherCount = dcount(ProcessCommandLine),
CipherList = make_set(ProcessCommandLine) by DeviceId, bin(Timestamp, 1m) 
// cipher.exe accessing multiple drives in a short timeframe 
| where CipherCount > 1

使用 wevtutil 从事件日志中清除取证证据

此查询检查是否尝试使用 wevtutil 从事件日志中清除至少 10 个日志条目。 运行查询

// Look for use of wevtutil to clear multiple logs
DeviceProcessEvents
| where Timestamp > ago(1d)
| where ProcessCommandLine has "WEVTUTIL" and ProcessCommandLine has "CL"
| summarize LogClearCount = dcount(ProcessCommandLine), ClearedLogList = make_set(ProcessCommandLine) by DeviceId, bin(Timestamp, 5m)
| where LogClearCount > 10

使用 sc.exe 关闭服务

此查询检查是否尝试使用sc.exe关闭至少 10 现有服务。 运行查询

// Look for sc.exe disabling services
DeviceProcessEvents
| where Timestamp > ago(1d)
| where ProcessCommandLine has "sc" and ProcessCommandLine has "config" and ProcessCommandLine has "disabled"
| summarize ScDisableCount = dcount(ProcessCommandLine), ScDisableList = make_set(ProcessCommandLine) by DeviceId, bin(Timestamp, 5m)
| where ScDisableCount > 10

关闭系统还原

此查询标识尝试停止系统还原并阻止系统创建还原点,这些还原点可用于恢复勒索软件加密的数据。 运行查询

DeviceProcessEvents
//Pivoting for rundll32  
| where InitiatingProcessFileName =~ 'rundll32.exe'   
//Looking for empty command line   
and InitiatingProcessCommandLine !contains " " and InitiatingProcessCommandLine != ""  
//Looking for schtasks.exe as the created process  
and FileName in~ ('schtasks.exe')  
//Disabling system restore   
and ProcessCommandLine has 'Change' and ProcessCommandLine has 'SystemRestore' 
and ProcessCommandLine has 'disable'

备份删除

此查询标识在加密之前使用 wmic.exe 删除卷影副本快照。 运行查询

DeviceProcessEvents
| where FileName =~ "wmic.exe"
| where ProcessCommandLine has "shadowcopy" and ProcessCommandLine has "delete"
| project DeviceId, Timestamp, InitiatingProcessFileName, FileName,
ProcessCommandLine, InitiatingProcessIntegrityLevel, InitiatingProcessParentFileName

检查勒索软件活动的多个迹象

除了单独运行多个查询,还可以使用综合查询来检查勒索软件活动的多个迹象,以识别受影响的设备。 以下合并查询:

  • 查找勒索软件活动的相对具体和微妙的迹象
  • 权衡这些迹象的存在
  • 识别成为勒索软件目标的几率较高的设备

运行时,此合并查询返回表现出多个攻击迹象的设备列表。 还会显示每种类型的勒索软件活动的计数。 若要运行此合并查询,请直接将其复制到 高级搜寻查询编辑器

// Find attempts to stop processes using taskkill.exe
let taskKill = DeviceProcessEvents
| where Timestamp > ago(1d)
| where FileName =~ "taskkill.exe" 
| summarize taskKillCount = dcount(ProcessCommandLine), TaskKillList = make_set(ProcessCommandLine) by DeviceId, bin(Timestamp, 2m)
| where taskKillCount > 10;
// Find attempts to stop processes using net stop
let netStop = DeviceProcessEvents
| where Timestamp > ago(1d)
| where FileName =~ "net.exe" and ProcessCommandLine has "stop"
| summarize netStopCount = dcount(ProcessCommandLine), NetStopList = make_set(ProcessCommandLine) by DeviceId, bin(Timestamp, 2m)
| where netStopCount > 10;
// Look for cipher.exe deleting data from multiple drives
let cipher = DeviceProcessEvents
| where Timestamp > ago(1d)
| where FileName =~ "cipher.exe" 
// cipher.exe /w flag used for deleting data 
| where ProcessCommandLine has "/w" 
| summarize CipherCount = dcount(ProcessCommandLine), 
CipherList = make_set(ProcessCommandLine) by DeviceId, bin(Timestamp, 1m) 
// cipher.exe accessing multiple drives in a short timeframe 
| where CipherCount > 1;
// Look for use of wevtutil to clear multiple logs
let wevtutilClear = DeviceProcessEvents
| where Timestamp > ago(1d)
| where ProcessCommandLine has "WEVTUTIL" and ProcessCommandLine has "CL"
| summarize LogClearCount = dcount(ProcessCommandLine), ClearedLogList = make_set(ProcessCommandLine) by DeviceId, bin(Timestamp, 5m)
| where LogClearCount > 10;
// Look for sc.exe disabling services
let scDisable = DeviceProcessEvents
| where Timestamp > ago(1d)
| where ProcessCommandLine has "sc" and ProcessCommandLine has "config" and ProcessCommandLine has "disabled"
| summarize ScDisableCount = dcount(ProcessCommandLine), ScDisableList = make_set(ProcessCommandLine) by DeviceId, bin(Timestamp, 5m)
| where ScDisableCount > 10;
// Main query for counting and aggregating evidence
DeviceProcessEvents
| where Timestamp > ago(1d)
| where FileName =~ "vssadmin.exe" and ProcessCommandLine has_any("list shadows", "delete shadows")
or FileName =~ "fsutil.exe" and ProcessCommandLine has "usn" and ProcessCommandLine has "deletejournal"
or ProcessCommandLine has("bcdedit") and ProcessCommandLine has_any("recoveryenabled no", "bootstatuspolicy ignoreallfailures")
or ProcessCommandLine has "wbadmin" and ProcessCommandLine has "delete" and ProcessCommandLine has_any("backup", "catalog", "systemstatebackup")
or (ProcessCommandLine has "wevtutil" and ProcessCommandLine has "cl") 
or (ProcessCommandLine has "wmic" and ProcessCommandLine has "shadowcopy delete")
or (ProcessCommandLine has "sc" and ProcessCommandLine has "config" and ProcessCommandLine has "disabled")
| extend Bcdedit = iff(ProcessCommandLine has "bcdedit" and ProcessCommandLine has_any("recoveryenabled no", "bootstatuspolicy ignoreallfailures"), 1, 0)
| extend ShadowCopyDelete = iff (ProcessCommandLine has "shadowcopy delete", 1, 0)
| extend VssAdminShadows = iff(ProcessCommandLine has "vssadmin" and ProcessCommandLine has_any("list shadows", "delete shadows"), 1, 0)
| extend Wbadmin = iff(ProcessCommandLine has "wbadmin" and ProcessCommandLine has "delete" and ProcessCommandLine has_any("backup", "catalog", "systemstatebackup"), 1,0)
| extend Fsutil = iff(ProcessCommandLine has "fsutil" and ProcessCommandLine has "usn" and ProcessCommandLine has "deletejournal", 1, 0)
| summarize FirstActivity = min(Timestamp), ReportId = any(ReportId), Commands = make_set(ProcessCommandLine) by DeviceId, Fsutil, Wbadmin, ShadowCopyDelete, Bcdedit, VssAdminShadows, bin(Timestamp, 6h)
// Joining extra evidence
| join kind=leftouter (wevtutilClear) on $left.DeviceId == $right.DeviceId
| join kind=leftouter (cipher) on $left.DeviceId == $right.DeviceId
| join kind=leftouter (netStop) on $left.DeviceId == $right.DeviceId
| join kind=leftouter (taskKill) on $left.DeviceId == $right.DeviceId
| join kind=leftouter (scDisable) on $left.DeviceId == $right.DeviceId
| extend WevtutilUse = iff(LogClearCount > 10, 1, 0)
| extend CipherUse = iff(CipherCount > 1, 1, 0)
| extend NetStopUse = iff(netStopCount > 10, 1, 0)
| extend TaskkillUse = iff(taskKillCount > 10, 1, 0)
| extend ScDisableUse = iff(ScDisableCount > 10, 1, 0)
// Adding up all evidence
| mv-expand CommandList = NetStopList, TaskKillList, ClearedLogList, CipherList, Commands, ScDisableList
// Format results
| summarize BcdEdit = iff(make_set(Bcdedit) contains "1" , 1, 0), NetStop10PlusCommands = iff(make_set(NetStopUse) contains "1", 1, 0), Wevtutil10PlusLogsCleared = iff(make_set(WevtutilUse) contains "1", 1, 0),
CipherMultipleDrives = iff(make_set(CipherUse) contains "1", 1, 0), Fsutil = iff(make_set(Fsutil) contains "1", 1, 0), ShadowCopyDelete = iff(make_set(ShadowCopyDelete) contains "1", 1, 0),
Wbadmin = iff(make_set(Wbadmin) contains "1", 1, 0), TaskKill10PlusCommand = iff(make_set(TaskkillUse) contains "1", 1, 0), VssAdminShadow = iff(make_set(VssAdminShadows) contains "1", 1, 0), 
ScDisable = iff(make_set(ScDisableUse) contains "1", 1, 0), TotalEvidenceCount = count(CommandList), EvidenceList = make_set(Commands), StartofBehavior = min(FirstActivity) by DeviceId, bin(Timestamp, 1d)
| extend UniqueEvidenceCount = BcdEdit + NetStop10PlusCommands + Wevtutil10PlusLogsCleared + CipherMultipleDrives + Wbadmin + Fsutil + TaskKill10PlusCommand + VssAdminShadow + ScDisable + ShadowCopyDelete
| where UniqueEvidenceCount > 2

了解和调整查询结果

合并查询返回以下结果:

  • DeviceId - 标识受影响的设备
  • TimeStamp - 首次在设备上观察到任何勒索软件活动迹象
  • 特定活动迹象 - 多个列中显示的每个符号的计数,例如 BcdEditFsUtil
  • TotalEvidenceCount - 观察到的符号数
  • UniqueEvidenceCount - 观察到的符号类型的数量

Microsoft Defender门户中勒索软件活动的合并查询示例

显示受影响设备和各种勒索软件活动迹象计数的查询结果

默认情况下,查询结果仅列出具有两种以上勒索软件活动类型的设备。 若要查看具有任何勒索软件活动迹象的所有设备,请修改以下 where 运算符,并将数字设置为零, (0) 。 若要查看更少的设备,请设置更大的数字。

| where UniqueEvidenceCount > 2

更多勒索软件资源

来自 Microsoft 的关键信息:

Microsoft 365:

Microsoft Azure:

Microsoft Defender for Cloud Apps:

Microsoft 安全团队博客文章:

提示

想要了解更多信息? Engage技术社区中的 Microsoft 安全社区:Microsoft Defender XDR技术社区