跳转到帖子

游客您好,欢迎来到黑客世界论坛!您可以在这里进行注册。

赤队小组-代号1949(原CHT攻防小组)在这个瞬息万变的网络时代,我们保持初心,创造最好的社区来共同交流网络技术。您可以在论坛获取黑客攻防技巧与知识,您也可以加入我们的Telegram交流群 共同实时探讨交流。论坛禁止各种广告,请注册用户查看我们的使用与隐私策略,谢谢您的配合。小组成员可以获取论坛隐藏内容!

TheHackerWorld官方

Windows事件查看器日志(evt)单一日志清除(II) ——程序 用于删除指定时间段内EVT文件的日志记录

精选回复

发布于

0x00 前言

Windows事件查看器日志(evt),清除单个日志系列文章的第二篇,介绍了删除EVT文件指定时间段内的日志记录的思想,解决了很多程序设计需要考虑的问题,并通过开源实现了代码。

0x01 简介

本文将介绍以下内容:

关于删除指定evt文件指定时间段日志记录的思考

计划实施细节

开放源代码

0x02 删除evt文件指定时间段日志记录的思路

与上一篇文章提到的删除evtx文件单个日志的方法相比,evt文件不能用同样的思路。

这是因为evt的文件结构不包含唯一值EventRecordID,因此无法定位指定的日志。

分析后发现可以选择日志的创建时间作为输入项,指定开始日期和结束日期,删除该时间段内的日志内容。

日志创建时间的格式是time_t类型,所以需要在time_t类型和格林威治标准时间(GMT)之间进行转换。

在方案实施上,思路如下:

遍历所有日志,筛选出符合删除条件的日志,保存剩余的日志内容。

筛选完成后,减去后续日志的记录数,再减去删除的日志数。

更新文件头中的文件记录结束偏移量、最后(最新)记录号和最大文件大小。

更新文件记录结束偏移量和文件记录结束中的最后(最新)记录号。

0x03 time_t类型和格林威治标准时间(Greenwich Mean Time,GMT)之间的转换

Calendar Time

日历,由time_t数据类型表示

意思是“相对时间”,可以避免受时区影响。不同时区的日历时间是相同的。

time_t类型:

本质上是一个长整数,表示从1970-01-01 00: 00到当前时间的秒数。

定义如下:

结构商标

{

int tm _ sec//分钟后的秒数- [0,60]包括闰秒

int tm _ min//小时后的分钟- [0,59]

int tm _ hour//自午夜起的小时- [0,23]

int tm _ mday//每月的某一天- [1,31]

int tm _ mon//自2011年1月以来的月份-[0]

int tm _ year//自1900年以来的年份

int tm _ wday//自周日以来的天数- [0,6]

int tm _ yday//自1月1日起的天数- [0,365]

int tm _ isdst//夏令时标志

};

注意年份是相对于1900年的。

Coordinated Universal Time(UTC)

协调世界时,也称为世界标准时间,是格林威治标准时间(GMT)。

时区有差异,所以计算当地时间时要考虑时差。

转换后的C代码示例如下:

格林威治时间的日历时间:

#包括

#包括

int main()

{

_ _ int64 CalTime=1531788377

struct tm GmTime

char GM buf[26];

_gmtime64_s(GmTime,CalTime);

strftime(GmBuf,26,' %m/%d/%Y %r ',GM time);

printf('GmTime :%s\n ',GmBuf);

返回0;

}

日历时间转换为当地时间(考虑时差):

#包括

#包括

int main()

{

_ _ int64 CalTime=1531788377

struct tm LocalTime

char local buf[26];

_localtime64_s(LocalTime,CalTime);

strftime(LocalBuf,26,' %m/%d/%Y %r ',local time);

printf('LocalTime:%s\n ',local buf);

返回0;

}

将时间转换为日历时间:

#包括

#包括

time _ t string todatetime(char * str)

{

TM TM _;

int年、月、日、小时、分钟、秒;

sscanf_s(str,' %d-%d-%d %d:%d:%d ',年,月,日,小时,分钟,秒);

tm_。TM _ year=year-1900;

tm_。TM _ mon=month-1;

tm_。tm _ mday=day

tm_。TM _ hour=hour-1;

tm_。tm_min=分钟;

tm_。tm_sec=秒;

tm_。TM _ isdst=0;

time _ t t _=mktime(TM _);

返回t _;

}

int main()

{

time _ t sec=StringToDatetime(' 2018-7-16 17:46:17 ');

printf('\n%ld\n ',秒);

返回0;

}

0x04 程序实现细节

1、结构体定义

文件头的定义可以在以下文件中找到:

https://technet.microsoft.com/zh-cn/library/bb309024

有关事件记录的定义,请参考:

https://technet.microsoft.com/zh-cn/library/aa363646

结束文件记录的定义可以在以下文件中找到:

https://technet.microsoft.com/zh-cn/library/bb309022

注:

在程序实现上,为了避免重定义,我修改了事件记录的结构名。

typedef struct _EVTLOGRECORD {

双字长度;

DWORD保留;

DWORD记录号;

DWORD TimeGenerated

DWORD TimeWritten

DWORD EventID

WORD EventType

WORD NumStrings

WORD EventCategory

WORD ReservedFlags

DWORD ClosingRecordNumber

DWORD StringOffset

DWORD UserSidLength

DWORD UserSidOffset

DWORD数据长度;

DWORD数据偏移量;

} EVTLOGRECORD,* PEVTLOGRECORD

2、筛选条件

Endfilerecord的TimeGenerated是一个固定结构,值为0x3333333。

在遍历的过程中,如何满足TimeGenerated为0x33333333,表示已经定位到文件记录的结尾,遍历结束。

3、遍历方法

while(currentRecordPtr-time generated!=0x3333333)

{

if(currentRecordPtr-TimeGeneratedTimeGeneratedEndTimeNum)

{

//没有选中evt记录,复制它

}

其他

{

//删除记录

}

currentRecordPtr=nextRecordPtr;

nextRecordPtr=(PEVTLOGRECORD)((PBYTE)nextRecordPtr nextRecordPtr-Length);

}

4、日志保存

日志文件的完整内容是通过读取文件获得的,并存储在数组中。

如果要删除日志中间的内容,需要删除数组中间一段的内容。

这里选择一个新定义的数组,遍历过程中只复制满足条件的日志。

我选择用memcpy。优点是第一个参数可以指定起始地址。

5、删除日志计数

统计删除日志总数,减去后续日志的记录数,减去删除日志总数。

减去事件记录的最后(最新)记录号和文件记录的结尾,以减去已删除日志的总数。

完整代码是开源的,下载地址:

https://github.com/3gstudent/Eventlogedit-evt-General/blob/master/evtdeleterecodoffile . CPP

Sys1.evt下载地址:

https://github.com/3gstudent/Eventlogedit-evt-通用/blob/master/sys1.evt

读取程序文件sys1.evt,删除2018年7月16日至2018年7月16日指定时间17: 46: 17,46: 40的4条日志。

生成文件sys2.evt和sys3.evt。

尾随空值不会从sys2.evt中移除

Sys3.evt删除尾随的空值

0x05 小结

介绍了删除evt文件指定时间段内日志记录的思想和程序实现细节。开源代码与删除evtx文件的方法有很大不同。

而且目前系统规定的指定时间段内删除evt日志记录的方法和evtx有很大不同,下一部分会详细介绍。

留下回复

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。