第5题 -- 简单方法暴删文件 write by http://hi.baidu.com/weolar/ (解答的很仓促,有错在所难免,欢迎大家拍砖) 第五题解答思路: 本题有多种解法,由于时间原因我只实现了个比较不好的方法。 不过本方法实现简单,完全不依赖系统ntfs,基本磁盘驱动以上的hook都能无视并暴力删除。 用XueTr扫一下可以发现驱动加载后hook了NtfsCheckValidAttributeAccess 和NtfsOpenAttributeInExistingFile这两个ntfs内部的函数。这两个hook点选的还是 比较好的,一是够深入够隐蔽,二是到文件系统这层基本就能杜绝那些文件名绕过等技巧了。 能首先想到的是反hook。虽然题目要求是不能干扰钩子,但可以钻题目的空子:NtfsCheckValidAttributeAccess 是函数头jmp的hook,在NTFS里查找引用这个函数的地方, 只会在NtfsOpenFcbById NtfsOpenExistingPrefixFcb NtfsOpenFile NtfsCreateNewFile这几个地方用到, 所以我们可以在这几个函数用到的地方再hook一下,直接跳转到NtfsOpenAttributeInExistingFile + 5地址。 而绕过NtfsCheckValidAttributeAccess就更好办了,这里的hook只是把call 的地址改了。 我们可以在NtfsCheckValidAttributeAccess 的函数头hook一下。这样就能完美绕过hijackFile的钩子了。不够这种方法太取巧……我放弃了。 (事实证明放弃是对的,因为这招不给分,呵呵……) 第二种方式是直接操作ntfs的文件系统,自己写扇区实现。我把ntfs-3g的代码移植到vc上, 不过倒楣的是移植的版本有点老,使用起来貌似有bug,要改还是有点麻烦……我又放弃了。 第三种方式是黑盒分析后得出的。首先可以确定hijackFile的钩子不会对D盘的相同路径的360safe过滤, 也就是说它的钩子有检测关于卷的信息。我把卷设备对象和相关的VPB、ntfs的设备对象copy了一份分别测试, 发现只有当ntfs的设备对象不同的时候才能删除文件。所以可以得出结论, hijackFile的钩子有验证ntfs的设备对象(暂时称pNtfsDev) 的某个域。但其实pNtfsDev是个很大的结构体,结构体的开始部分才是DEVICE_OBJECT类型。 其余的是文件系统自带的结构(VCB等)。 如果能找出钩子验证的是哪个域就能伪造一份。由于驱动被加密,逆向很麻烦,可以这样分析:先获取 pNtfsDev的地址,当运行到钩子的时候填充一部分pNtfsDev所指向的内存为0.如果系统崩溃的话说明钩子会访问相关的域。 这样几次测试后就能确定是哪个域,然后根据进行伪造。但VCB的结构是不公开的, 这个就麻烦了,很难确定这个域是干嘛用的。所以我又放弃了。 (不过现在知道了,是MFT号) 最后找到一种比较简单的绕过方式:重加载文件系统方式。可以这样:预先加载我的山寨版ntfs,这个ntfs被我修改过,比如设备名是MyNtfs。加载后myntfs会通过IoRegisterFileSystem注册一个文件系统的 设备对象(实际上就是放入一个链表)。这个设备对象是专门用来被系统在IopMountVolume的时候 在一个链表里检测到然后用来操作挂载的。 。然后将卷设备、VPB、各copy一份,把vpb的flag位清空,随后手动挂载MyNtfs。 这样就能获取能用来操作文件的pNtfsDev(实际上也就是 PVOLUME_DEVICE_OBJECT)。由于是自己的文件系统,所以想删什么文件都没问题了。 (当然,如果是直接替换系统原来的, 可以直接右键删除,我的代码删了一句话, 实际实现也是这个效果。不过这个效果有点bug,后面会提到。) 这样有个问题,系统原来open过的文件再用MyNtfs能进行操作么?事实是可以的, 因为open(也就是create)操作后系统保存的是file_object, 这个是会保存原ntfs的PVOLUME_DEVICE_OBJECT。所以以前的open操作后要继续操作, 走的是原ntfs路线,新open操作就走的是MyNtfs了。 系统重启后可能有dskchk。这是由于MyNtfs在某个扇区里写了个标志位,本来想去掉,想想不管了……代码见附件。 注意,运行代码前先用工具加载MyNtfs.sys。 MyNtfs的代码见本论坛或debugman。附件提供了个bin,改动不大。 又及: 当时匆忙搞完后没仔细跟。现在又看了一遍,发现了个疏忽,实际上代码里面的挂载ntfs的代码没起作用, 真正挂载到系统的是系统的IopMountVolume。具体原因还不明,貌似是NtfsReadMftRecord里读缓存失败, 读的是个空的。不过系统的偏偏能成功……暂时交给各位来搞吧。 所以这题我做的很失误,难怪dskchk检查ntfs有错误。因为和系统原版NTFS有冲突。不过思路是对的,欢迎大家继续研究。 谢谢观看,各位新年愉快~
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!