1.4 隐藏的文件系统
TDL3是第一个将配置文件和有效负载存储在目标系统隐藏的加密存储区域的恶意软件系统,不依赖于操作系统提供的文件系统服务。今天,TDL3的方法已经被其他复杂的威胁所采用和适应,如Rovnix Bootkit、ZeroAccess、Avatar和Gapz。
这种隐藏的存储技术严重妨碍了取证分析,因为恶意数据存储在硬盘驱动器上某个位置的加密容器中,但在操作系统本机文件系统所保留的区域之外。同时,该恶意软件能够使用传统的Win32 API接口访问隐藏文件系统的内容如CreateFile
、ReadFile
、WriteFile
和CloseHandle
。通过允许恶意软件开发人员使用标准的Windows接口从存储区域读取和写入有效负载,简化了恶意软件有效负载的开发,并且无须开发和维护任何自定义接口。这一设计决策意义重大,因为与使用标准接口挂钩一起,它提高了Rootkit的整体可靠性。从软件工程的角度来看,这是一个很好的代码重用示例。微软CEO的成功法则是:“开发者,开发者,开发者,开发者!”换句话说,就是将现有的开发技能视为宝贵的资本。TDL3采取了类似的方式,利用开发人员现有的Windows编程技能,但是如果这被用在恶意代码的开发中,会简化转换,并且增加恶意代码的可靠性。
TDL3在操作系统自己的文件系统未占用的扇区中分配硬盘上隐藏文件系统的映像。映像从磁盘的末端向起始端增长,这意味着如果它增长到足够大,将可能最终覆盖用户的文件系统数据。映像被分成1024字节的块。第一个块(在硬盘驱动器的末尾)包含一个文件表,其条目描述文件系统中包含的文件,并包括以下信息:
- 文件名限制为16个字符,包括终止字符null。
- 文件的大小。
- 实际文件偏移量,通过从文件开头的偏移量减去文件开始的偏移量乘以1024来计算。
- 文件系统创建的时间。
文件系统的内容按照每个块使用自定义(大部分是特别的)加密算法加密。不同版本的Rootkit使用不同的算法。例如,一些修改使用RC4密码,它使用与每个块对应的第一个扇区的逻辑块地址(LBA)作为密钥。但是,另一个修改使用具有固定密钥的XOR操作加密数据:0x54增加了每个XOR操作,导致加密太弱,很容易发现对应于包含0的加密块的特定模式。
在用户模式下,有效负载通过打开名为\Device\XXXXXXXX\YYYYYYYY的设备对象的句柄来访问隐藏存储,其中XXXXXXXX和YYYYYYYY是随机生成的十六进制数字。请注意,访问此存储的代码路径依赖于许多标准的Windows组件,希望这些组件已经被调试过并且是可靠的。设备对象的名称在每次系统引导时生成,然后作为参数传递给负载模块。Rootkit负责维护和处理对这个文件系统的I/O请求。例如,当有效负载模块对存储在隐藏存储区域的文件执行I/O操作时,操作系统将此请求传输给Rootkit,并执行其入口点函数来处理该请求。
在这种设计模式中,TDL3说明了紧跟Rootkit的一般趋势。Rootkit没有为所有的操作提供全新的代码,让第三方恶意软件开发者不得不学习这些代码的特性,而是依靠现有的和人们熟悉的Windows功能—只要它的搭载技巧和底层的Windows界面不是众所周知的即可。特定的感染方法随着大规模部署的防御措施的变化而演变,但是这种方法一直存在,因为它遵循了恶意软件和良性软件开发共享的通用代码可靠性原则。