高级WIN2KROOTKIT检测技术-Win2000教程
转载自:互联网 作者:cd3c.com
您正在看的Win2000教程是:高级WIN2KROOTKIT检测技术。
摘要:本文描述了一种检测内核与用户级rootkit的新技术.此技术利用处理器的单步执行模式,来测定系统内核与DLL中执行指令的数量,从而达到检测rootkit和后门的目的.同时还讨论了其在Win2k下的代码实现.
--背景知识
一个在计算机安全领域中重要的问题是,如何判断给定的主机是否已被入侵.由于以下两点这项工作变的非常困难:
1.攻击者可以利用未知漏洞进入系统.
2.当进入系统后,入侵者可通过安装rootkit和后门来隐藏自身(例如:隐藏进程,通讯渠道,文件等).本文将集中讨论在Win2K系统下rootkit的检测问题.
--传统rootkit检测技术中的一些问题
传统的rootkit检测程序(那些我们经常在UNIX系统中见到的)只能检测一些已知的rootkit(这点使它变的像反病毒程序)或进行一些内核存储的扫描.例如Linux中就有一些工具扫描内核中的syscall table.这显然不够好,因为已经有了很多并不更改syscall table的rootkit,而Win2k下也可开发出类似的rootkit.
那检测程序是不是还应该扫描内核代码空间?这样我们就有了一个运行在内核模式中的Tripwire.但这还不够好,因为在大多数的操作系统中,我们可以写出即不更改SST(syscall table)也不更改代码的内核级rootkit.在系统中有很多可以勾连的函数指针(例见).
以我看,存储扫描技术决不会成为rootkit检测的终结.这主要是因为我们不能确定具体的监测存储区域.
那到底怎样检测出我们系统中的入侵者呢?
首先我们以rootkit中所使用的技术,将其分为两类:
*通过更改系统结构来隐藏某对象的(如运行的进程)和
*更改内核执行路径(例:勾连那些负责枚举活动进程的内核函数)来达到同样目的的.
--更改系统数据结构的rootkit
这类的rootkit不太多.有意思的例子包括fu rootkit(见),通过删除内核中PsActiveProcessList链上的进程对象来隐藏进程.ZwQuerySystemInformation等函数是不能发现这些隐藏进程的.但同时,因为Windows的线程分派器(dispatcher, scheduler)使用另外的数据结构,这些"隐藏"进程仍可运行(被分配到CPU使用时间).Windows的线程分派器使用以下三个(注1)数据结构:
*pKiDispatcherReadyListHead
*pKiWaitInListHead
*pKiWaitOutListHead
后两个是处于"等待"状态的线程链头.他们之间稍有不同,但对我们来说并不重要.
从上面的信息我们可以找到一种检测隐藏进程的方法.及读取线程分派器使用的数据结构,而不是PsActiveProcessList.
当检测rootkit时我们应该尽可能的触及更底层的内核数据结构.
有一点应该注意,直接从线程分派器使用的链中删除要隐藏的进程是不可能的,因为隐藏的进程将分配不到CPU使用时间.
--更改执行路径的rootkit
这类的rootkit较为普及.他们通过修改或增加内核或系统DLL中的指令来达到目的.检测这类rootkit的问题是,我们不知道rootkit在什么地方做了那些修改.它可以勾连DLL中的函数,系统服务列表(System Service Table),改变内核函数的内容或修改内核中一些奇怪的函数指针.
--执行路径分析(Execution Path Analysis)
EPA关注这样一个事实:如果入侵者通过修改执行路径隐藏了一些对象,那么当调用一些典型的系统和库的函数时,系统将运行一些多余的指令.
举个例子,如果入侵者为了隐藏文件和进程而修改了ZwQueryDirectoryFile()和ZwQuerySysteminformation(),那样和干净的系统相比,这些系统函数就会执行更多的指令.不管入侵者采用勾连或在代码中加入jmp指令,或其他任何方法.指令增加的原因是rootkit必须进行它的任务(在这个例子中是隐藏文件和进程).
但是Windows 2000的内核是一个非常复杂的程序,即使在干净的系统中,某些系统函数每次运行的指令个数也是不同的.然而我们可以用统计学来解决这个问题.但首先,我们需要一种测定指令个数的方法......
--指令计数器的实现
单步执行模式是Intel处理器的一个好的特性,我们可以用它来实现指令计数.当处理器处在这个模式时,每执行完一条指令,系统将产生一个除错异常(debug exception, #DB).要进入这个模式,需要设置EFLAGS寄存器中的TF位(详见).
当执行int指令时,处理器会自动清TF位并进行权限切换.这意味着,如果要进行内核模式下的指令计数,则必须在中断处理程序开头设置TF位.因为我们将要测定一些系统服务中的指令个数,勾连中断向量0x2e,也就是Windows 2000下的系统服务调用门会变得很有效.
但是,因为存在用户模式的rootkit,也应该测定在ring3级运行的指令个数.只要在用户模式下设置TF位一次就可以了,从内核返回时,处理器会自动恢复这一位.
以上的计数方法通过内核驱动器实现.如图2所示,驱动加载后勾连IDT 0x1和0x2e.为和用户级程序交互.驱动勾连一个系统调用,用户级程序通过这个特定的系统调用来开关计数器.
--一些测试
我们可以使用上一段中描述的方法来测定任意系统服务中执行的指令个数.
例如,来检查是否有人试图隐藏任意文件,我们可以开始一个简单的测试:
pfStart();
FindFirstFile("C:\\WINNT\\system32\\drivers", &FindFileData);
int res = pfStop();
如果有rootkit隐藏任意文件,则执行的指令数要比干净的系统多.
如果运行这个测试上百次,并计算执行指令数的平均值,我们会发现这个值是非常不确定的.考虑Win2k的复杂性,这一点也不让人吃惊.但对于我们的检测目的来说,这种现象是不能接受的.但如果我们将得到的那些值的频率分布用条形图表示出来,会发现图中有一个明显的频率高点.如图4和5中所表示那样的,即使是在系统负载很大时,频率高点所对应的数值保持不变.很难解释这个令人吃惊的现象,可能是因为在循环中同一个系统服务被调用几百次后,与这个系统服务相关的缓冲最后会被填入固定的值.
假想现在有人安装了隐藏文件的rootkit,如果我们重复测试并绘制相应的条形图,就会发现频率高点向右移了,这是因为rootkit需要进行隐藏文件的工作.
在现在的代码实现中,只进行了少量的测试,包括典型的服务如:文件系统读取,枚举进程,枚举注册表项以及Socket读取.
这些测试将有效地检测出著名的NTRootkit(见),或最近比较流行的Hacker Defender(见),包括它自带的网络后门,当然还包括很多其他的后门.但要检测出一些更好的后门还要加入一些新的测试.
--误报和执行路径跟踪
虽然对频率高点的检测有助于我们处理系统的不确定因素,但有时会发现测试得到的值有小的差值,一般来说不大于20.
有时这会是一个很严重的问题,因为我们不能确定那些多出来的指令意味着被入侵或只是正常的误差.
为解决这个问题,我们使用了执行路径记录模式.和单一的EPA模式比较,系统增加了对执行路径的记录(包括地址和运行的指令),首先,系统记录下正常情况下的执行路径,以后的每一次运行将产生diff文件(正常系统和现行系统之间的比较).
我们应该使用好的反编译器来分析那些不一样的地方,以此判定他们是否可疑.图6是一个diff文件的例子.
现阶段的diff文件只记录下指令的地址,以后可能将两次测试的不同结果存为PE格式文件,并可用
[1] [2] 下一篇
