Windows单条日志清除系列文章的第一篇,侧重于介绍基础知识和删除单条日志的实现思路与实例
本文将要介绍以下内容:
evtx文件格式
删除单条日志的思路
删除单条日志的实例
可参考的资料:
https://github.com/williballenthin/python-evtx
evtx文件是指Windows Vista之后用于保存系统日志信息的文件
evtx文件结构包含三部分:
file header
chunks
trailing empty values
注:
file header保存evtx文件基本信息,值得注意的是Next record identifier、Number of chunks、File flags和Checksum
chunks保存日志内容,包括具体每条日志的内容和校验和,值得注意的是Last event record number、Last event record identifier、Last event record data offset和两个Checksum
trailing empty values为尾随空值,用于填充文件长度,内容任意,不会影响evtx文件的有效性
格式可参考:
https://github.com/libyal/libevtx/blob/master/documentation/Windows%20XML%20Event%20Log%20(EVTX).asciidoc#2-file-header
格式可参考:
https://github.com/libyal/libevtx/blob/master/documentation/Windows%20XML%20Event%20Log%20(EVTX).asciidoc#3-chunk
chunks包含多个Event Record,1个Event Record对应一条日志信息
格式可参考:
https://github.com/libyal/libevtx/blob/master/documentation/Windows%20XML%20Event%20Log%20(EVTX).asciidoc#32-event-record
Event Record的内容以Binary XML格式保存
Binary XML格式可参考:
https://github.com/libyal/libevtx/blob/master/documentation/Windows%20XML%20Event%20Log%20(EVTX).asciidoc#4-binary-xml
值得注意的是EventRecordID标签,用来表示日志的顺序号
查看事件日志,选中一条日志,选择详细信息
->XML视图
如下图
安装python-evtx:
pip install python-evtx
下载脚本:
https://github.com/williballenthin/python-evtx/blob/master/scripts/evtx_record_structure.py
命令如下:
evtx_record_structure.py System.evtx 1915
回显如下:
Windows系统在解析日志文件时,通过Event Record的Size长度逐个读取每一条日志的内容
如果修改某条日志的长度,使长度覆盖下一条日志,那么Windows系统在解析时,就会跳过下一条日志,相当于下一条日志被隐藏
DanderSpritz中的eventlogedit就是这个思路,只修改了长度,没有删除日志内容
实现思路如下图
注:
图片来自https://blog.fox-it.com/2017/12/08/detection-and-recovery-of-nsas-covered-up-tracks/
所以如果恢复每条日志的正确日志长度,就能够恢复出被隐藏的日志,恢复工具可使用如下python脚本:
https://github.com/fox-it/danderspritz-evtx
当然,如果以此为基础,把指定日志的内容清空,就能够实现真正的日志删除
为了保证修改后的日志文件能够被正确识别,还需要修改多个标志位,重新计算校验和
具体修改方法如下:
File header中的Next record identifier值减1
重新计算File header中的Checksum
修改Event Record:重新计算待删除Event Record前后长度,更新后续Event Record的Event record identifier
更新ElfChuk,修改如下内容:
Last event record number
Last event record identifier
Last event record data offset
Event records checksum
Checksum
测试文件: System.evtx
下载地址:
https://github.com/3gstudent/Eventlogedit-Evolution/raw/master/System.evtx
文件包含4条日志,下面演示如何删除第4条日志
第4条日志内容如下图
EventRecordID为1915
File header位于文件最开始的部分
Next record identifier的偏移为24(0x18h),长度8
对应测试文件System.evtx,如下图
Next record identifier为0x77Ch,即1916
减1后为1915,即0x77Bh
计算方法: 前120字节做CRC32运算,偏移为124(0x7Ch),长度4
修改Next record identifier后的内容如下图
前120字节的内容为456C6646696C6500000000000000000000000000000000007B0700000000000080000000010003000010010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
计算CRC32可使用如下python代码:
import binascii def crc2hex(crc): return '%08x' % (binascii.crc32(binascii.a2b_hex(crc)) & 0xffffffff) d='456C6646696C6500000000000000000000000000000000007B0700000000000080000000010003000010010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' print(crc2hex(d))
输出结果ccc94756
所以更新后的内容为56 47 C9 CC
,如下图
通过搜索magic string 0x2A 0x2A 0x00 0x00
定位不同的Event Record
第四条Event Record的内容如下图
长度为0x138h
Event record identifier为0x77Bh
第三条Event Record的内容如下图
长度为0x480h
Event record identifier为0x77Ah
修改第三条Event Record的长度,使其覆盖第四条Event Record
新长度为0x138h+0x480h=0x5B8h
由于是删除最后一条日志,所以不需要更新Event record identifier(共有两个位置)
注:
修改长度的位置有两个,分别为第三条日志的长度和第四条日志的最尾部
修改后如下图
注:
本次测试只修改了Event Record的长度,后续可通过修复长度还原日志
当然可以选择将日志内容清空,实现永久删除
搜索magic string ElfChuk
注:
有可能有多个ElfChuk,需要找到对应的ElfChuk
测试文件System.evtx只有一个ElfChuk
内容如下图
Last event record number为0x4h
Last event record identifier为0x77Bh
Last event record data offset为0x1248h
Event records checksum为0xD3D3DE43h
Checksum为0xEB4C47BFh
需要做如下修改:
Last event record number减1,为0x3h
Last event record identifier减1,为0x77Ah
Last event record data offset为第三条Event Record相对于ElfChuk的偏移长度,为0xDC8h
Event records checksum为所有Event records内容的CRC32校验和,包含3条日志内容,使用python脚本计算后,结果为0xF92FEDB9h
Checksum为ElfChuk中0-120和128-512这些内容的CRC32校验和,结果为0x3CE0BF8h
更新后,内容如下图
保存为新文件System2.evtx
下载地址:
https://github.com/3gstudent/Eventlogedit-Evolution/raw/master/System2.evtx
注:
为了验证trailing empty values,我将第四条日志后的内容全部覆盖为0x41(字符A),不影响日志文件的有效性
System2.evtx被成功识别,如下图
本文介绍了基础知识和删除单条日志的实现思路,实例演示如何修改evtx文件,隐藏最后一条日志
下一篇将要介绍如何编写程序实现自动删除指定日志