删除Windows事件纪录--听起来简单做起来难的销声匿迹

今天要研究是接续上篇的Windows XML Event Log (EVTX),要进入他的事件纪录本身,我们把文件分为文件标头(file header)、资料块(chunks)、尾随空值(trailing empty values)区块,上次讲到纪录记在chunk里,在其chunk header後会有一笔笔用2a2a0000当签名开头的纪录,每笔纪录在FileTime之後,也就是纪录的24 byte後,就是他的XML文档,每笔纪录的最後会再抄一次这笔纪录的大小当作结尾,而今天要讲的就是这个XML文档的写法,即使有参考资料,对照自己的文件也花了一些时间,下面是笔者努力看懂的部分,如果哪里说得不好请各个大大见谅~


[MS-EVEN6]协定的二进位XML

一样的,我们复制%SystemRoot%\System32\Winevt\Logs的Setup.evtx作为范例,看到1218行(16进位),前面刚结束8个byte的FileTime,後面接着是用[MS-EVEN6]协定的二进位XML文件,通常向下会有四个部分:

  • Prologue (XML PI) (0到1个)
  • Fragment (0到多个)
  • Miscellaneous (XML PI) (0到1个)
  • End of file token

我们的范例没有Prologue,他主要是XML文件的一种宣告,我们往下看Fragment,他包含fragment header跟一个element或template instance。
Imgur

fragment header总共有4个byte长,原则上都会以0f01 0100开头,包含fragment header的token跟版本号等。
Imgur

再来是一个element或template instance,我们的范例档以Template instance这种纪录居多,他的大小可变,以0c开头做作为Template instance的token,後面会有Template的定义段跟Template的资料段,这两段的大小也不一定,里面也会有数据大小的资料。
Imgur

如果遇到的是element,则会有下面几种物件:

  • OpenStartElementTag:01或41,就是XML始标签的开头”<”符号
  • CloseStartElementTag:02,就是XML始标签的结尾”>”符号
  • 内容本身
  • EndElementTag:04,就是XML的尾标签,即
  • CloseEmptyElementTag:03,就是XML空标签的结尾”/>”符号

好,我尽力了……後面的判读实在看不懂又对不上,不过这已经对文档局格有基础的理解,这样可以做到一些事,我们可以尝试删除一笔纪录,在事件检视器中,日志都只能全部清空或自动覆写,无法删除单笔,有了这两天的知识,我们其实可以来个实作做到手动改写日志:


删除一笔纪录

Imgur
图片来源:https://blog.fox-it.com/2017/12/08/detection-and-recovery-of-nsas-covered-up-tracks/

这是一个删除日志的示意图,我们说每笔纪录会以2a2a0000作为开头签名,有几笔纪录就应该要有几个2a2a0000,这个我们先称他叫Record Header,後面会写纪录的长度,并在纪录的结尾再写一次,那如果我们把长度延伸到下笔记录,就意味着中间记录的删除,也就是改写成图中的New Size,不过当然,後面还要改写校验值等等让文件合理,我们就一步步往下做,记得日志先备份,我们同样以范例的Setup.evtx做改写,尝试修改最後一笔记录。

1.

File Header的Next recordidentifier要减掉一,上篇提到这份日志存了96笔记录,下一笔是97,因为这里要删除一笔,所以下一笔的指标就会是96,所以我们把第25个byte的61改成60。
Imgur

2.

再来File Header的资料改完了,所以接下要去第124 byte後修改4个byte的CheckSum,重新计算一遍前120 byte的CRC32值才会通过校验程序,这里笔者计算完是A36BA7FA(计算的时候input要设定为Hex而不是ASCII,笔者找到的计算机),记得用小端写法,所以要写faa7 6ba3。
Imgur

3.

因为Chunk header的修改需要用到新的记录结尾位置,所以我们先到Event Record改Size,可以查询最後一个2a2a0000,应该要是最後一笔记录,可以看到後面的60代表是我们要删除的第96笔记录,中间e001 0000表示长度有480个byte,往前看到上笔记录的结尾f001 0000表示长度有496个byte。
Imgur

所以480+496=976个byte,换成十六进位就是03d0,小端写法就是d003 0000,把这个新的Size放进第95笔资料在开头显示的大小,和第96笔资料在结尾显示的大小。
Imgur
Imgur

4.

最後回到Chunk header,如果有多个Chunk就是找最後一个,这里只有一个所以就是4096 byte之後。
Imgur

首先要把Last event record number跟Last event record identifier从60改成5f表示记录到95笔。
Imgur

再来是Chunk header的44 byte後的Last event record data offset,他是描述从Chunk header到最後一笔资料前的大小,所以现在是a628也就是42536个byte,减掉倒数第二笔(第95笔)资料的大小(496 byte),就会变成42040 byte(a438),所以我们要把这个指标改为小端写法 38a4 0000。
Imgur

接着是Event records checksum,他是从块头结束的第一笔记录开始一直到最後一笔记录结束,这段资料的CRC32值,也就是第4096+512=4608 byte开始到最後一笔资料的结尾也就是最後一个d003 0000(原第96笔资料记录大小的结尾),笔者计算完的结果是327CBA0B,小端写法0bba 7c32。
Imgur

最後则是在Chunk header有一个Checksum,他位在整个标头的第124 byte後4个byte,他是整个Chunk header的前120 byte跟128-512 byte的CRC32值,直接删掉中间的8个byte合并成504个byte的资料段去计算就对了,用十六进位的说法就是找位址0×1000-0×1078,0×1080-0×1200(0x表示16进位的意思),笔者这里计算完是0xC6540581,小端写法8105 54c6。
Imgur

整个Chunk header修改完:
Imgur


验证修改

接着我们到事件检视器,在右侧栏位按开启储存的记录,打开刚刚修改完的档案……我在这里犹豫了许久,这是一整篇下来唯一一个可以测试的地方,失败就要全部重检查,结果竟然过了!皆大欢喜差点在半夜叫出来~~
Imgur

我们可以看到这里的记录确实变成95笔,而我们照日期排序一看,跟之前在系统的比对会发现,他的确删除了最後一笔资料,也就是最新的一笔记录,选这个记录档也是因为他比较不常更动。
Imgur

如果我们有修改错误,像是某个checksum算错,就会无法开启像下面这样:
Imgur

至於复原就是把刚刚做的全部倒回去做就对了,网路上似乎也有工具可以做得到,而上述的方法也是NAS方程序组织的DanderSpritz中的eventlogedit实现方式,不过说到底其实只是隐藏资料,真正要删除的话就是要把刚刚最後一笔记录的部分全部改写成00做清空。

写到这里才发现自己缺的东西很多,从一开始的大小端,编辑16进位的文件,CRC32值一开始还以为是10进位的格式又转换一遍,直到後来对原文件计算才知道是错的又继续找,发现还要把文件内容当作hex值input进去,中间几度看不doc在写什麽,看着别人做不会发现实际的困难,有兴趣的话你也可以尝试,总之这样子,假设我们都对这些日志了解了,下篇就来解决问题吧~~

Imgur

参考资料:
https://github.com/libyal/libevtx/blob/main/documentation/Windows%20XML%20Event%20Log%20(EVTX).asciidoc
https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/444383/
https://blog.fox-it.com/2017/12/08/detection-and-recovery-of-nsas-covered-up-tracks/
https://www.convertworld.com/zh-hant/numerals/hexadecimal.html
https://crccalc.com/


<<:  Day 18 AWS云端实作起手式第八弹 让开机器变得很自动自发Auto Scaling-WriteNode设置

>>:  #16 数据上的各种距离(1)

Day 17 - [语料库模型] 05-实体对应

在语句中常会出现概念相似的词,包括某类物品、地名、时间...等。例如,轮椅、拐杖、助行器、电动床都属...

DAY15 注册按钮功能实现

if isinstance(event, PostbackEvent): # 如果有normal讯息...

[C 语言笔记--Day19] Condition Code 帮忙做出 C 语言的 if 语法

大纲 C 语言中的 if x86-64 中的 condition code MSP430 的 sta...

离职倒数28天:日本人办婚礼不登记的理由

跟老同事们说离职时,我很意外很多人第一个问题居然是问我是不是要结婚了。第一个人问时还有点反应不过来,...

Day 7:AWS是什麽?30天从动漫/影视作品看AWS服务应用 -《PSYCHO-PASS心灵判官》part1

提到健康监控系统,就不可不提鼎鼎大名的《PSYCHO-PASS心灵判官》中的希必拉系统Sibyl S...