Windows XML Event Log (EVTX)单条日志清除(三)——通过解除文件占用删除当前系统单条日志记录
0x00前言关于在Windows事件日志(evtx)中清除单个日志的系列文章的第三篇介绍了删除当前系统EVTX日志文件中单个日志记录的第一种方法:关闭服务对应的进程,释放文件句柄,移除文件占用,删除日志,重新启动服务。
0x01简介
本文将介绍以下内容:
通过C程序枚举服务信息,提取事件日志服务对应的进程svchost.exe的pid,通过C程序关闭事件日志进程,通过C程序释放文件句柄,通过C程序删除单个日志文件0x02。
上一篇文章《Windows XML Event Log (EVTX)单条日志清除(二)——程序实现删除evtx文件的单条日志记录》介绍了删除单个日志记录的方法,但是如果直接用来删除当前系统的日志,打开文件时会报错,提示文件被占用。
这是因为当前系统启动日志服务Eventlog后,会以独占模式打开日志文件,导致其他进程无法打开日志文件,从而无法修改。
有两种解决方案:
结束日志服务Eventlog对应的进程,释放文件句柄,获取修改日志文件的权限,在日志服务Eventlog对应的进程中获取指定日志文件的句柄,使用句柄修改日志文件。本文将首先介绍解决方案,分享程序实现的细节,最后开源实现代码。
第二种解决方案将在下一篇文章中详细介绍。
0x03获取对应于事件日志服务的进程svchost.exe的pid
Windows系统有多个svchost.exe进程,无法直接搜索进程名‘svchost . exe’获取Eventlog服务对应的进程pid。
探究思路:
枚举当前系统服务,根据服务名称过滤出对应的进程pid。
1.由powershell实现
代码如下:
get-WmiObject-Class win32 _ service-Filter ' name=' event log ' | select-exp ProcessId
2.由c实现。
0x04向右抬起关闭事件日志进程
1.由powershell实现
执行cmd命令taskkill。
2.由c实现。
c的代码需要权限提升才能结束这个过程,svchost.exe。
注意:
完成事件日志服务对应的流程后,一定时间后,事件日志服务会自动重启。
0x05释放文件句柄
事件日志服务对应的进程完成后,需要释放日志文件的句柄,才能获得文件修改权限。
实施思路:
使用NtQuerySystemInformation查询SystemHandleInformation获取所有进程的句柄信息,挑出日志进程中的所有句柄,释放句柄的关键代码如下:
0x06修改
日志文件,删除日志记录结束Eventlog服务对应的进程后,获得了操作日志文件的权限,修改日志文件的方法和c代码可参考上一篇文章《Windows XML Event Log (EVTX)单条日志清除(二)——程序实现删除evtx文件的单条日志记录》
代码参考地址:
https://github.com/3gstudent/Eventlogedit-evtx--Evolution/blob/master/DeleteRecordbyTerminateProcess.cpp
代码实现了自动获得日志服务的进程,结束进程,释放句柄,修改指定的系统日志文件内容,修改成功后重新启动日志服务
程序测试如图:
更新(2018.7.29)
在github上看到了另外一种实现思路,地址如下:
https://github.com/360-A-Team/EventCleaner/blob/master/EventCleaner/
值得注意的是日志删除使用了WinAPI EvtExportLog
值得注意的是日志删除使用了WinAPI EvtExportLog
利用EvtExportLog对日志文件进行过滤,过滤条件为去除某一条日志,这样新生成的文件就是删除单条日志后的文件
优点是不用考虑日志删除的细节,文件格式不会出错,方便高效,并且修改过滤条件可以很容易删除一段时间内的日志
但是存在一点不足:
对于删除日志的后续日志,没有更新EventRecordID
举个简单例子:
Security.evtx下面有10条日志,EventRecordID为1-10,通过EvtExportLog删除第8条日志,第9和第10条日志的EventRecordID不变,仍然为9和10,但是删除后的日志总数为9,EventRecordID依次为1-7,9,10
我的代码中采用的方法虽然能解决这个问题,但是需要考虑很多细节和意外情况,程序实现上比较复杂
所以,我在我的工程中也加入了利用EvtExportLog删除日志的方法,地址如下:
https://github.com/3gstudent/Eventlogedit-evtx--Evolution/blob/master/DeleteRecordbyTerminateProcessEx.cpp
代码实现了自动获得日志服务的进程,结束进程,释放句柄,利用EvtExportLog修改指定的系统日志文件内容,修改成功后重新启动日志服务
程序测试如图:
0x07 其他细节
某些情况下,关闭Eventlog进程和重启服务Eventlog会产生日志文件,位于system.evtx下,EventID为7034和7036
为了避免产生日志7034和7036,可通过关闭日志服务Eventlog线程的方法关闭日志记录功能
关闭日志服务Eventlog线程的powershell实现代码:
https://github.com/hlldz/Invoke-Phant0m
关闭日志服务Eventlog线程的c实现代码:
https://github.com/3gstudent/Windwos-EventLog-Bypass
介绍细节的分析文章:
《利用API NtQueryInformationThread和I_QueryTagInformation实现对Windwos日志监控的绕过》
在实际应用中,通常是先线程挂起,最后再恢复线程
参考地址:
https://github.com/3gstudent/Eventlogedit-evtx--Evolution/blob/master/SuspendorResumeTid.cpp
代码支持挂起、恢复和结束日志服务的线程,可用来关闭和恢复日志记录功能
0x08小结
本文介绍了通过关闭服务对应的进程,释放文件句柄,解除文件占用,删除当前系统单条日志记录的方法。
优化关闭日志记录功能的代码,添加挂起和恢复的代码,支持关闭和重新开启系统的日志功能
脉搏地址:https://www.secpulse.com/
微博地址:https://weibo.com/311057789/home?wvr=5