0x00前言


Windows XML Event Log (EVTX)单条日志清除系列文章的第三篇,介绍第一种删除当前系统evtx日志文件单条日志记录的方法:关闭服务对应的进程,释放文件句柄,解除文件占用,删除日志,重启服务


0x01简介


本文将要介绍以下内容:

  • 通过c程序枚举服务信息,提取Eventlog服务对应进程svchost.exe的pid

  • 通过c程序提权关闭Eventlog进程

  • 通过c程序释放文件句柄

  • 通过c程序删除单条日志文件


    0x02删除思路


    在上篇文章《Windows XML Event Log (EVTX)单条日志清除(二)——程序实现删除evtx文件的单条日志记录》介绍了删除单条日志记录的方法,但如果直接用来删除当前系统的日志,在打开文件时会报错,提示文件被占用

    这是因为当前系统启动日志服务Eventlog后,会以独占模式打开日志文件,导致其他进程无法打开该日志文件,也就无法进行修改操作

    有以下两种解决方法:

    1. 结束日志服务Eventlog对应的进程,释放文件句柄,获得修改日志文件的权限

    2. 获得日志服务Eventlog对应进程中指定日志文件的句柄,利用该句柄实现日志文件的修改

    本文将要介绍第一种解决方法,分享在程序实现上的细节,最后开源实现代码

    第二种解决方法会在之后的文章进行详细介绍


    0x03获得Eventlog服务对应进程svchost.exe的pid


    由于Windows系统有多个svchost.exe进程,无法直接搜索进程名"svchost.exe"获得Eventlog服务对应的进程pid

    查询思路:

    枚举当前系统服务,根据服务名称筛选出对应的进程pid

    1、通过powershell实现

    代码如下:

    Get-WmiObject -Class win32_service -Filter "name = 'eventlog'" | select -exp ProcessId


    2、通过c++实现

    0x04提权关闭Eventlog进程


    1、通过powershell实现

    执行cmd命令taskkill即可


    2、通过c++实现

    c++的代码需要提升权限才能结束进程svchost.exe

    注:

    结束Eventlog服务对应的进程后,隔一段时间后Eventlog服务会自动重启



    0x05 释放文件句柄


    结束Eventlog服务对应的进程后,还需要释放日志文件的句柄,才能够获得文件的修改权限

    实现思路:

    1. 利用NtQuerySystemInformation查询SystemHandleInformation获得所有进程的句柄信息 

    2. 挑选出日志进程中的所有句柄 

    3. 释放句柄


    关键代码如下:



    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为70347036

    为了避免产生日志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小结


    本文介绍了通过关闭服务对应的进程,释放文件句柄,解除文件占用,删除当前系统单条日志记录的方法。

    优化关闭日志记录功能的代码,添加挂起和恢复的代码,支持关闭和重新开启系统的日志功能

    源链接

    Hacking more

    ...