Windows rootkits of 2005, part one(翻译)

来源:互联网 发布:大话西游2魔6坐骑数据 编辑:程序博客网 时间:2024/05/19 20:59
出于学习计算机和英语的目的,尝试翻译一些英文的技术帖,我尽量翻译准确,然而不能保证,感兴趣的请参看原文:http://www.securityfocus.com/infocus/1850

阅读基础:保护模式,PE文件格式,设备驱动程序

                                             Windows rootkits of 2005, part one
                                         James Butler, Sherri Sparks 2005-11-04

        2005年,恶意软件技术达到了一个新的高度。随着一些使用windows rootkit技术的新病毒、蠕虫、间谍软件以及广告软件等等的出现使得这种提高从来没有像现在这般明显。于是,了解它带来的威胁以及如何发现这种恶意用法的重要性日益增加。

        本文将分3部分讨论rootkit。第一部分讨论什么是rootkit,以及为何rootkit这么危险。我们将从察看各种执行模型和访问内核的方法(如hook表,分层过滤驱动以及直接处理windows内核对象等)开始。第二部分讲述用虚拟内存hook进行高度隐秘活动的最新的windows rootkit方法。最后讨论发现rootkit的各种方法以及专业的安全策略。

Rootkit的定义
        Rootkit是入侵者用来在计算机系统中隐藏自己的一个或一组程序,并且允许以后也能够访问该计算机。为了达到这个目的,rootkit修改了操作系统的运行流程或者处理操作系统依赖的审查和记录的数据集。
        Rootkit并不是exploit,而是入侵者在exploit之后使用的手段。通常,rootkit比exploit有趣些,甚至比0-day exploit更有趣。大多数人很难接受这个现实,即我们的计算机系统总是会不断地被发现弱点,计算机的安全都是关于风险的管理。0-day exploit只是一颗子弹,而rootkit则会带给我们更多的关于入侵者的信息,比如他扳动扳机的动机是啥。通过分析rootkit的行为,我们可以确定入侵者想窃取什么,他在与谁通讯,以及入侵者的老练程度。不过,在我们分析为什么之前,先看看怎么做。

特权模式(Privilege modes)
        Windows被设计为安全的,健壮的系统,其内核必须被保护起来。但是用户程序需要某些内核的功能。为了提供这些功能,Windows实现了2个运行模式:用户模式和内核模式。尽管Intel和AMD的CPU都支持4种特权模式来保护系统代码和数据不被恶意或者无意的更低的特权代码覆盖,但Windows现在只支持2种。
         应用程序运行在用户模式下,用户模式的进程没有特权。
         内核模式是指被授权访问所有系统内存和所有处理器指令的运行模式。比如系统服务可以遍历运行在内核模式中的系统服务描述表(SSDT)。第三方设备驱动也是运行在内核模式,因为很多时候,他们必须访问低级的内核函数和对象以及硬件接口。
        Windows标记访问每个内存页面需要的模式,但是内核状态下不限制其他内核模式的线程对其访问。
        当我们把目光转向Windows rootkis, 我们很快就发现rootkit也分为2类,分别对应处理器的用户模式和内核模式。用户模式rootkit可以作为一个单独的程序运行,也可以运行在一个已经存在的程序里。内核模式的rootkit则拥有操作系统的所有权力,可以破坏整个系统!

执行路径钩子(Execution path hooks)
        为了改变操作系统的正常执行路径,rootkit使用了hook技术。现代操作系统中都被设计成有弹性,可扩展并且向后兼容,所以有很多地方可以hook。rootkit使用hook修改原始操作系统函数返回的信息。Windows操作系统中有很多表可以被hook,下面会列出一些。

导入地址表钩子(Importe address table hooks)
        Windows被设计为与计算机硬件底层相关性极低,并且与其他操作系统环境兼容,如POSIX。同时也必须很灵活,即使升级了操作系统,应用程序开发人员也不必重写代码。Windows通过提供三个环境子系统达到这个目的。这3个子系统就是:Win32子系统,POSIX子系统和OS/2子系统。每个子系统都通过动态库来实现。这些子系统提供一个接口给内核下的系统服务。应用程序开发人员通过API来编写程序可以在大多数操作系统升级的情况下还可使用。一般情况下,应用程序不会直接调用Windows系统服务,而是通过某个子系统来完成该过程。这些动态库导出了文档化的接口,应用程序链接到这些子系统就可以调用这些接口。Win32子系统是最常用的子系统,它由Kernel32.dll,User32.dll,Gdi32.dll和Advapi32.dll组成。Ntdll.dll是系统提供给各个子系统的一个特殊的库。它提供了一些stub来将各个请求分发到Windows执行系统服务,最后Windows执行系统服务将控制权移交到内核模式中的SSDT才真正执行实际的操作。这些stub包含了特别的代码结构,可以切入到内核模式。
        当Windows加载可执行文件到内存时,加载器必须文件中一个被称为导入地址表(IAT)的section。IAT中列出了该文件用到的动态库以及各个动态库中被用到的函数。加载器定为每一个动态库在磁盘中的位置,并把它们也映射到内存中。然后加载器将那些函数的地址写入调用这些函数的执行文件的IAT中。一般IAT中的函数都是Kernel32.dll和Ntdll.dll到处,也有一些其他有用的函数有其他库导出,比如Ws2_32.dll导出的socket函数。内核设备驱动同样从其他库中导入函数到内核的内存中,比如Ntoskrnl.exe和Hal.dll。
        通过修改执行文件IAT的入口,rootkit可以修改程序的运行流程并且修改原函数本来想要返回给调用者的东东。假设一个应用程序列出一个目录下的所有的文件,并且针对它们作一些操作。这个程序可能是运行在用户模式下的用户程序或者服务。同时假设这个程序是个Win32程序,这意味着它会使用Kernel32.dll,User32.dll,Gui32.dll和Advapi.dll最后去调用内核函数。在Win32下,要列出一个目录下的所有文件,应用程序首先是调用FindFirstFile,这个是Kernel32导出的。FindFirstFile调用成功后会返回一个句柄。接下来通过返回的句柄迭代调用FindNextFile遍历该目录下的所有文件和子目录。FindNextFile也是Kernel32.dll的导出函数。由于应用程序使用了这些函数,所以加载器会把Kernel32.dll加载到内存,并把这些函数的地址记录到应用程序的IAT中。当应用程序调用FindNextFile的时候,只是跳转到导入表中的一个地址,然后再从这跳转到FindNextFile函数在Kernel32.dll中的地址。FindFirstFile的处理也是一样的。FindNextFile调用Ntdll.dll中的NtQueryDirectoryFile函数。该函数把内核函数中相应的系统服务号存到EAX寄存器,把用户空间中的参数地址存到EDX寄存器,然后调用一条INT 2E指令或者SYSENTER指令跳入到内核。

        在上面的例子中,rootkit通过改写IAT使其指向rootkit的函数,而不是原本指向Kernel32.dll。Ntdll.dll也是如此处理。攻击者利用这种技术都做什么事情在很大程度上依赖于他的想象力。rootkit可以调用原函数然后对结果进行过滤来隐藏一些东西,比如文件,目录,注册表键值,进程等。这里要注意一下,因为每个进程都有他自己的虚拟地址空间,rootkit想要改变应用程序的IAT,就必须跨越进程的边界。Richter和Pietrek在这方面各自都有很好的处理办法。关于跨越进程边界的详细解释参见[ref 1],[ref 2],[ref 3]。

系统服务描述表钩子(System Service Descriptor Table hooking)
        如前所诉,Win32子系统只是rootkit可以hook的各个地方之一。然而,它却是通往内核的唯一途径。操作系统函数真实的实现地址记录在内核的一个表中。该表就是系统服务描述表(SSDT),也被称为系统调用表。那些地址对应于Ntoskrnl.exe中的NtXXXX系列的函数。内核模式的rootkit可以直接修改SSDT,用它自己的代码替换它需要的NtXXX函数。跟hook单个应用程序的IAT不同,这种技术设置了一个系统钩子,可以影响每一个进程。威力太大了!拿上一节中IAT hook的例子来说,内核模式的rootkit可以hook NtQueryDirectoryFile来隐藏本地文件系统的文件和目录。

内联函数钩子(Inline function hooking)
        内联函数钩子比IAT或者SSDT钩子更先进。相对于替换一个表中的指针的方法,内联函数钩子替换原始函数的几个字节的方法更容易发现。一般来说,rootkit会增加一个无条件跳转指令从原函数转移到rootkit代码中。许多Windows API函数都是以下面的标准形式开始:

     Code Bytes   Assembly
     8bff               mov edi, edi
     55                 push ebp
     8bec             mov ebp, esp

        在内联函数钩子时,rootkit先保存它将要覆盖的原始代码以便维持该函数相同的行为,然后用一个跳转语句改写原来的入口使其转到rootkit的代码中。注意,rootkit能够安全的覆盖函数的前5个字节是因为很多跳转指令或者call指令的长度都是5字节,恰好在一个指令边界上。

        机器码         汇编代码

     e9 xxxxxxxx    jmp xxxxxxxx

        这里的"xxxxxxxx"是rootkit的代码地址。rootkit可以跳转到原始地址加一些偏移(译注:这个偏移就是修正rootkit的代码地址与原函数入口地址的差异),并且修改原来操系统返回的数据。
内联函数钩子和其他大多数rootkit技术一样,有很多合理的用途。[ref 4]是Microsoft Research在一个会议上的关于内联函数钩子的第一份文档,如今Microsoft对其的发展已经远远超越了研究的用途。他们称其为"hot patching",该技术允许系统打补丁不用重启。

分层过滤驱动(Layered filter drivers)
        分层过滤驱动现在是rootkit比较新的应用,可以将自身插入到操作系统的执行流中。操作系统的很多重要特性最终都是通过设备驱动来处理的,比如网络通讯和文件存储。Windows允许开发人员将过滤驱动放在当前已经存在的驱动程序的顶部,以便在不改写底层驱动的情况下扩展其特征。许多病毒扫描程序实现文件过滤驱动来扫描文件,就如同它们自己打开的文件一样。操作系统提供的文件驱动将结果往上传给杀毒软件的文件过滤驱动,然后文件过滤去冬就能扫描该文件了。Rootkis也可以用这种分层技术改变文件文件的访问和列举,改变socket通信和列举等。

直接操作内核对象(Direct Kernel Object Manipulation)
        直接操作内核对象(DKOM)依赖于一个事实:操作系统为了能够记录和审核,它创建了内核对象。如果rootkit修改这些内核对象,就可以让操作系统相信有些东东存在或者不存在于系统中。通过修改一个token对象,rootkit可以改变操作系统信任的对象执行某个动作,因此破坏任何记录。比如,FU[ref 5] rootkit修改描述系统中进程对象的的内核对象。所有的内核进程对象是通过一个链表链接在一起的,当一个用户进程比如TaskMgr.exe通过API向操作系统查询进程列表,Windows遍历进程对象链表返回相应的信息。FU将它要隐藏的对象从链表中删掉,于是乎,应用程序发现这个进程不存在。

Rootkis in the wild
        虽然现在存在很多的rootkit,但是他们大都差不多。可以把他们分成两类:一类使用hook,另一类使用DKOM。按这样分类,Hacker Defender[ref 6]是hook类型中最流行的。它隐藏进程、服务、文件、目录、注册表键以及端口。FU则是使用DKOM技巧中最流行的。然而,FU仅仅是被编写用来验证概念,没有任何隐藏自己的企图,并且也没有包含一个远程通讯通道进去。FU可以隐藏进程和设备驱动,也可以提升任何Windows进程token的权限和组。

第一部分综述:

         从windows rootkits的历史来看,它已经存在了一段时间了。只是从去年或者前年开始被原来越容易的用于病毒、广告软件、蠕虫和间谍软件等恶意软件上。Hacker Defender的作者甚至出售他还没有被病毒扫描软件以及rootkit扫描软件发现的的rootkit版本。正是这种恶意的解决方案造成了严重的威胁。

        在第二部分将介绍持久的和基于内存的rootkits,包括使用虚拟内存提供高度隐蔽性的高级rootkit。最后在第三部分讨论查找这些rootkit的侦测方法,最小化其带来的威胁。


参考:
[ref 1] Pietrek, Matt. "Learn System-Level Win32® Coding Techniques by Writing an API Spy Program." Microsoft Systems Journal Volume 9 Number 12.


[ref 2] Richter, Jeffrey. "Load Your 32-bit DLL into Another Process's Address Space Using INJLIB." Microsoft Systems Journal Volume 9 Number 5.


[ref 3] Richter, Jeffrey. Programming Applications for Microsoft Windows fourth edition. Redmond: Microsoft Press, 2000. pp. 751-820.


[ref 4] Hunt, Galen C. and Doug Brubacker, "Detours: Binary Interception of Win32 Functions" Proceedings of the 3rd USENIX Windows NT Symposium, July 1999, pp. 135-43.

[ref 5] FU. http://www.rootkit.com

[ref 6] Hacker Defender by Holy Father. http://hxdef.czweb.org/

原创粉丝点击