如何在系统日志中记录WMI Persistence?
导语:攻击者通常会利用WMI来实现远程执行(如wmiexec)和后门(如WMIPersistence),然而Windows系统默认不会在日志中记录这些操作。
About:
1. Monitor WMI Persistence 2. Instructions about ExportsToC++ 3. My test of using DiskCleanup on Windows 10using DiskCleanup
目录:
1. 介绍如何在系统日志中记录WMI Persistence,测试并分析如何绕过 2. dll劫持中会用到的一个辅助工具,自动读取dll的导出函数并生成对应的c++代码 3. 实际测试《using DiskCleanup on Windows 10 usingDiskCleanup》,记录过程,虽然测试失败,但其中包含的绕过思路值得学习
Monitor WMI Persistence
简介
攻击者通常会利用WMI来实现远程执行(如wmiexec)和后门(如WMIPersistence),然而Windows系统默认不会在日志中记录这些操作。于是Timothy Parisi和Evan Pena提出了他们的解决方法:
利用WMI Persistence的方法记录攻击者调用WMI的操作,并将以下结果写入系统日志中,监控系统实时读取系统日志,及时提醒用户受到攻击
1. Event Consumer Name 2. Event Consumer Command 3. Process Call Method 4. Process Call Command
实际测试
作者开源了一个powershell脚本,下载地址如下:https://github.com/realparisi/WMI_Monitor/blob/master/WMIMonitor.ps1
注:powershell版本需要3.0或者更高,以管理员权限运行
测试系统:
Windows 8.1 x86 Powershell v3.0
1、运行脚本开启监控
2、模拟攻击者新建一个定时启动后门
powershell代码如下:
wmic在cmd下直接实现的代码如下:
注:代码具体含义在《WMI Attacks》、《WMI Backdoor》、《WMI Defense》、《Study Notes of WMI Persistence using wmic.exe》作过具体介绍,此处略
3、查看系统日志
控制面板-系统和安全-查看事件日志-事件查看器(本地)-Windows日志-应用程序
找到事件ID为8的事件,查看详细信息,如图
记录了如下信息:
==New WMI Consumer Created== Consumer Name: BotConsumer23 Command Executed:C:WindowsSystem32notepad.exe
4、结论
系统日志成功记录攻击者留下的后门
站在攻击者角度的思考
如果攻击者能够实现WMI Persistence,代表其已经获得了管理员权限,那么可通过如下命令来查看已注册的WMI信息:
通过powershell查看的代码:
Filters:
Get-WMIObject -Namespace rootSubscription-Class __EventFilter
Event Consumers:
Get-WMIObject -Namespace rootSubscription-Class __EventConsumer
Event Bindings:
Get-WMIObject -Namespace rootSubscription-Class __FilterToConsumerBinding
通过wmic查看的代码:
Filters:
wmic/NAMESPACE:"rootsubscription" PATH __EventFilter GET __RELPATH/FORMAT:list
Event Consumers:
wmic/NAMESPACE:"rootsubscription" PATH CommandLineEventConsumer GET__RELPATH /FORMAT:list
Event Bindings:
wmic/NAMESPACE:"rootsubscription" PATH __FilterToConsumerBinding GET__RELPATH /FORMAT:list
如图,能够查看防御者留下的监控代码,那么当然可以通过命令行来删除监控,而更重要的是查看和删除操作不会被记录到日志中
通过powershell实现的删除代码如下:
综上,站在攻击者的角度,可能的绕过方法如下:
(1) 查看EventFilter 和 EventConsumer instances (2) 删除监控功能的WMI实例 (3) 留下自己的WMI后门 (4) 手动再次开启监控功能的WMI实例
补充
公开的POC powershell脚本仅作为演示,在实际防御中要对以下操作进行记录:
_FilterToConsumerBinding,__EventFilter, and__EventConsumer instances
简介
在实现UACBypass或者Persistence的时候常常会用到dll劫持,实现dll劫持通常会先使用dumpbin查看dll的导出函数,构造一个具有相同导出函数的dll,并在其中添加payload。ExportsToC++ 就是为了简化这个过程,尤其对于包含多个导出函数的dll,大大简化了这个过程。
实际测试
下载地址如下:https://github.com/michaellandi/exportstoc
需要环境:
.NET 2.0 Framework 安装Microsoft Visual Studio
测试实例:
https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/
https://3gstudent.github.io/3gstudent.github.io/Userland-registry-hijacking/
目的:劫持计划任务UserTask,实现开机启动自己的dll,弹框
方法:
1.在HKEY_CURRENT_USERSoftwareClassesCLSID下新2 2.建项{58fb76b9-ac85-4e55-ac04-427593b1d060} 3. 新建项InprocServer32
值设定为新dll的绝对路径:c:testtestexport.dll
劫持的原dll路径:c:Windowssystem32dimsjob.dll
步骤:
1、运行exportstoc
下载工程并编译,直接运行会报错,如图
解决方法:运行dumpbin需要VS编译环境,在Visual Studio Tools中找到Developer CommandPrompt for VS2012.lnk并运行,在弹出的cmd下运行ExportsToC++.exe
2、生成c++代码
打开原dll:c:Windowssystem32dimsjob.dll
选择Convert-To C++ Wrapper,输入原dll的绝对路径:c:Windowssystem32dimsjob.dll
自动生成可供使用的c++代码,如下:
3、编译
使用vc6.0新建dll工程,添加以上代码并加上payload:
MessageBox(NULL,”testexport”,”testexport”,MB_OK);
编译并保存为c:testtestexport.dll
4、修改注册表,劫持UserTask
powershell代码如下:
5、注销用户,重启测试
弹框成功
使用Process Explorer查看进程taskhost.exe,成功加载新的dll,如图
注:在https://3gstudent.github.io/3gstudent.github.io/Userland-registry-hijacking/中使用的方法弹框后taskhost.exe进程报错,未给出bug的解决方法,本文介绍的方式能够解决这个bug
简介
Win10系统中存在一个叫作”SilentCleanup”的计划任务,任务运行时会作如下操作:
1. 以high权限运行cleanmgr.exe 2. 创建临时目录C:UsersAppDataLocalTempGUID 3. 将system32Dism下的DismHost.exe及其运行时需要加载的dll复制到该临时目录 4. 以high权限运行DismHost.exe 5. 删除临时目录所有内容
绕过思路
1. 监控临时目录的生成 2. 替换复制到该临时目录的dll,为确保及时,覆盖DismHost.exe最后加载的dll:LogProvider.dll 3. DismHost.exe启动时加载替换过的dll,实现UACBypass
POC脚本
下载地址:https://gist.github.com/mattifestation/b4072a066574caccfa07fcf723952d54
实际测试
测试系统:
Win10 x64
补丁:KB3173428(无法手动卸载)
测试过程:
1、正常启动计划任务SilentCleanup
开启ProcessMonitor
手动开启服务SilentCleanup
cleanmgr.exe创建临时目录
切换到临时目录查看复制过来的dll
high权限运行的DismHost.exe
2、通过POC脚本启动计划任务并测试
开启ProcessMonitor
根据LogProvider.dll的导出函数编写新的dll(过程略,可参考0x02)
执行poc脚本
临时目录创建成功
接下来出现两种情况:
(1)LogProvider.dll替换失败 (2)脚本显示dll文件替换成功,输出显示UACBypass成功,然而新的dll并没有加载
查看临时目录,发现创建两个GUID文件夹,一个是包含正常LogProvider.dll的目录,另一个是LogProvider.dll被替换成新dll的目录
DismHost.exe正常启动,但没有加载新的dll
测试失败
补充:
虽然测试失败,但是绕过思路值得学习:
1. POC通过注册WMI事件来监控特定文件目录 2. 当目录下有特定文件生成的时候对其替换 3. 进而实现dll劫持
这种替换思路在其他方面也会用到,值得收藏。
发表评论