win7产生大量evtx文件_Windows XML Event Log (EVTX)单条日志清除(四)——通过注入获取日志文件句柄删除当前系统单条日志记录...

本文介绍了如何通过枚举进程句柄、Dll注入和内存映射来删除Windows EVTX日志文件中的特定记录,详细阐述了实现思路、步骤和代码示例,涉及进程间消息传递和利用EvtExportLog API筛选日志。
摘要由CSDN通过智能技术生成

0x00 前言

Windows XML Event Log (EVTX)单条日志清除系列文章的第四篇,介绍第二种删除当前系统单条日志记录的方法:获得日志服务Eventlog对应进程中指定日志文件的句柄,通过Dll注入获得该句柄的操作权限,利用该句柄实现日志文件的修改

0x01 简介

本文将要介绍以下内容:

利用思路

程序实现

枚举日志服务Eventlog对应进程的所有句柄,获得指定日志文件的句柄

通过Dll注入获得该句柄的操作权限

进程间消息传递的方法

0x02 利用思路

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

那么,如果我们通过Dll注入进入进程的内存,接着获得指定日志文件的句柄,能否获得该日志文件的操作权限呢?

0x03 枚举日志服务Eventlog对应进程的所有句柄,获得指定日志文件的句柄

1、利用工具processhacker获得指定日志文件的句柄

下载地址:

https://processhacker.sourceforge.io/

(1)获得日志服务Eventlog对应进程的pid

执行如下powershell代码:

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

(2)运行processhacker

根据pid找到进程,查看Properties->Handles

能够获得当前进程的所有句柄信息

如下图

2-1.png

可以看到C:\Windows\System32\winevt\Logs\Security.evtx对应的Handle值为0x1c8

2、通过c++程序实现获得指定日志文件的句柄

查看processhacker的源码,寻找实现方法

代码位置:

https://github.com/processhacker/processhacker/blob/e2d793289dede80f6e3bda26d6478dc58b20b7f8/ProcessHacker/hndlprv.c#L307

获得参考资料:

On Windows 8 and later, NtQueryInformationProcess with ProcessHandleInformation is the most efficient method.

On Windows XP and later, NtQuerySystemInformation with SystemExtendedHandleInformation.

Otherwise, NtQuerySystemInformation with SystemHandleInformation can be used.

于是,挑选第三个方法尝试实现

注:

经测试,第三个方法适用于Win7和更新版本的操作系统

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

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

接着通过NtDuplicateObject获取句柄的名称和具体的数值信息

最后筛选出想要查找的句柄,输出Handle值

完整实现代码已开源,下载地址如下:

https://github.com/3gstudent/Homework-of-C-Language/blob/master/GetPIDandHandle(evtx).cpp

代码实现了根据输入的关键词进行搜索,获得对应的句柄名称和Handle值

测试如下图

2-2.png

成功获得日志服务Eventlog对应进程的pid,security.evtx对应的Handle值为0x1c8

0x04 通过Dll注入获得该句柄的操作权限

通过NtCreateThreadEx + LdrLoadDll实现Dll注入的代码可参考:

https://github.com/3gstudent/Homework-of-C-Language/blob/master/NtCreateThreadEx%20%2B%20LdrLoadDll.cpp

注:

注入成功后需要FreeDll

注入成功后,使用获得到的Handle值作为函数CreateFileMapping()的第一个参数,创建一个文件映射内核对象

然后调用函数MapViewOfFile()将文件数据映射到进程的地址空间

接下来修改内存中的数据,删除单条日志记录

最后调用函数FlushViewOfFile(),将内存数据写入磁盘

0x05 进程间消息传递的方法

在实际使用过程中,整个实现日志记录删除功能的代码要放在Dll中,而通过CreateRemoteThread无法向Dll传入参数,这就导致无法删除指定EventlogRecordId的日志

这里可以借助进程间的消息传递

实现方法有多种,例如信号、管道、消息队列和共享内存,甚至是读写文件

由于在0x04部分使用了函数CreateFileMapping()创建一个文件映射内核对象,所以进程间消息传递也使用内存映射的方式

创建一个共享内存,代码可参考:

https://github.com/3gstudent/Homework-of-C-Language/blob/master/OpenFileMapping.cpp

代码中创建了两个内存映射对象,并且指定了函数CreateFileMapping()的访问权限为允许任何人访问该对象,即函数CreateFileMapping()的第二个参数

通常情况下,该值设置为NULL,表示默认访问权限,但在注入的Dll中必须设置为允许任何人访问该对象,否则提示拒绝访问

原因如下:

Dll注入svchost.exe后,权限为System,默认访问权限无法访问由用户创建的内存映射文件对象,必须指定为允许任何人访问该对象

当然,如果是两个用户权限的进程进行消息传递,函数CreateFileMapping()的第二个参数为NULL即可

读取指定共享内存,代码可参考:

https://github.com/3gstudent/Homework-of-C-Language/blob/master/OpenFileMapping.cpp

代码中读取这两个内存映射对象,添加了数据类型转换的功能(字符串转int)

0x06 程序实现流程

1、自己解析格式,实现日志删除

删除的关键代码如下:

https://github.com/3gstudent/Eventlogedit-evtx--Evolution/blob/master/DeleteRecordofFile.cpp

代码实现了删除文件c:\test\Setup.evtx中的一条日志(EventRecordID=14),新文件保存为c:\test\SetupNew.evtx

整个实现流程分成两部分:

启动程序

注入的Dll

1.启动程序(Loader-rewriting.cpp)

代码地址:

https://github.com/3gstudent/Eventlogedit-evtx--Evolution/blob/master/Loader-rewriting.cpp

流程如下:

获得日志服务Eventlog对应进程的pid

枚举日志服务Eventlog对应进程的的所有句柄,获得指定日志文件的句柄

创建两个内存映射,用于向dll传递日志文件的句柄和需要删除日志的EventRecordID

向日志服务Eventlog对应的进程注入Dll

释放Dll

关闭内存映射

2.注入的Dll(Dll-rewriting.cpp)

代码地址:

https://github.com/3gstudent/Eventlogedit-evtx--Evolution/blob/master/Dll-rewriting.cpp

流程如下:

分别从两个内存映射读取消息,将读取到的内容从字符串转换成int类型,获得日志文件的句柄及需要删除日志的EventRecordID

调用函数CreateFileMapping(),传入日志文件的句柄,创建一个文件映射内核对象

调用函数MapViewOfFile()将文件数据映射到进程的地址空间

修改内存数据,删除指定日志

调用函数FlushViewOfFile(),将内存数据写入磁盘

关闭日志文件的内存映射

测试如下图

3-1.png

2、使用WinAPI EvtExportLog,过滤出想要删除的内容

可供参考的代码:

https://github.com/360-A-Team/EventCleaner/blob/master/EventCleaner/EventCleaner.cpp#L528

我按照这个思路写的代码:

https://github.com/3gstudent/Eventlogedit-evtx--Evolution/blob/master/DeleteRecordofFileEx.cpp

代码实现了调用Windows API EvtExportLog对日志文件进行筛选,去除指定日志后,将剩下的日志内容保存为新文件temp.evtx

整个实现流程分成三部分:

日志删除程序

启动程序

注入的Dll

1.日志删除程序(DeleteRecord-EvtExportLog.cpp)

代码地址:

https://github.com/3gstudent/Eventlogedit-evtx--Evolution/blob/master/DeleteRecord-EvtExportLog.cpp

流程如下:

指定日志文件和需要删除日志的EventRecordID

生成新的日志文件temp.evtx

2.启动程序(Loader-EvtExportLog.cpp)

代码地址:

https://github.com/3gstudent/Eventlogedit-evtx--Evolution/blob/master/Loader-EvtExportLog.cpp

流程如下:

获得日志服务Eventlog对应进程的pid

枚举日志服务Eventlog对应进程的的所有句柄,获得指定日志文件的句柄

创建三个内存映射,用于向dll传递日志文件的句柄、新日志文件的长度和新日志文件的内容

向日志服务Eventlog对应的进程注入Dll

释放Dll

关闭内存映射

3.注入的Dll(Dll-EvtExportLog.cpp)

代码地址:

https://github.com/3gstudent/Eventlogedit-evtx--Evolution/blob/master/Dll-EvtExportLog.cpp

流程如下:

从第一个内存映射获得日志文件的句柄,将读取到的内容从字符串转换成int类型

从第二个内存映射获得新日志文件的长度

根据新日志文件的长度调整内存映射的读取长度,从第三个内存映射获得新日志文件的内容

调用函数CreateFileMapping(),传入日志文件的句柄,创建一个文件映射内核对象

调用函数MapViewOfFile()将文件数据映射到进程的地址空间

修改内存数据,覆盖为新日志文件的内容

调用函数FlushViewOfFile(),将内存数据写入磁盘

关闭日志文件的内存映射

测试如下图

3-2.png

注:

对于以上两种方法,删除setup.evtx是没有问题的,删除system.evtx和security.evtx会存在因为竞争条件导致删除失败的情况

0x07 小结

本文介绍了第二种删除当前系统单条日志记录的方法:获得日志服务Eventlog对应进程中指定日志文件的句柄,通过Dll注入获得权限,利用该句柄实现日志文件的修改

某些情况下,dll注入会失败,那么是否还有删除当前系统单条日志记录的方法呢?下一篇文章将会介绍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值