蓝派网(www.lan27.com)-精选网络资源,分享和交流! 文章首页站内搜索在线手册广告代码酷站欣赏万年历
您现在的位置: 蓝派网 >> 文章中心 >> 电脑知识 >> 操作系统 >> 正文

Windows远程内核漏洞注入

作者:佚名    文章来源:网络转载    更新时间:2007-11-25 13:34:56
 


-----------------------------------------------------------------------------------------------------
 

核心区域与用户区域

       I386体系支持4种访问权限,也就是通常所说的特权级别。Windows NT 使用了其中的两个权限,使得NT操作系统可以在不完全支持这四种特权级别的体系中运行。
       用户区域代码例如应用程序和系统服务运行在3级,用户模式的进程只能访问分配给他们的20亿字节的内存,并且用户代码是可以被分页和上下文切换的。
       核心级代码运行在0级,硬件抽象层、设备驱动程序、IO、内存管理和图形接口都是运行在0级。在0级执行的代码,运行时拥有系统的所有权限,可以访问所有内存且能使用特权指令。

Native API

     由于设计,用户模式进程不能任意切换权限登记,这个功能会牵涉到整体Windows NT的安全模型。当然,这个安全模型是由多时段所构成的。
    有时候用户态的作业没有核心级函数功能无法完成,这就是引入Native API的原由。Native API是未被文档化的内部函数集,运行在内核模式。Native API之所以存在,就是为了提供一些能够在用户模式下安全地调用内核模式服务的途径。
    一个用户应用程序可以调用由NTDLL.DLL导出的Native API。NTDLL.DLL导出大量函数用于封装相应的内核函数。如果你反汇编其中一个函数,你会发现结果与下面相似:

Windows 2000:

mov eax, 0x0000002f

lea edx, [esp+04]

int 0x2e

         每个由NTDLL导出的Native API都可以被反编译成能够把执行环境切换到内核模式的代码段(stub).首先寄存器载入一个指向系统服务表的索引值,随后在NTOSKRNL对应偏移位置访问所需要的函数。

Windows XP:

mov eax, 0x0000002f

mov edx, 7ffe0300

call edx

At offset 0x7ffe0300:

mov edx, esp

sysenter

ret

    如果你的配置是奔腾II或者更高,那么在Windows XP中情况会有些不同。Windows XP是通过SYSENTER/SYSEXIT指令对来实现内核模式与用户模式的切换,这给创建shell code增加了一些困难,稍后再详细解释。
    为了成功的创建内核模式的shell code,你必须忘记所有用户级的API,且只使用内核级函数Native API。关于Native API的更多文档资料可以参考Gary Nebbett的《The Windows NT/2000 Native API Referce》。

蓝屏的本质

当你找到一个漏洞,当你把数据包发送到远程系统时面临着出现蓝屏的问题。要想成功注入一个内核级漏洞,首先要理解“蓝屏死机(Blue Screen Of Death)”的原理。
当你见到BSOD,这就意味着native函数KeBugCheckEx被调用,有两种情况可以引发这种错误:

1、由内核异常调用
2、直接由错误检测机制调用KeBugCheckEx


内核的异常链处理机制如下:
    当一个异常产生时,内核通过IDT(中断描述符表)的函数入口(KiTrapXX)取得控制权。这些函数组成了1级的的陷阱处理程序(Trap Handler),这个中断处理体可能会独自处理这个异常,也可能把该异常传递给下一个异常处理体,或者如果这个异常是无法处理的,那么就直接调用KeBugCheckEx。

    无论是哪种情况,为了掌握产生异常的原因和地点,我们需要得到陷阱桢(Trap Frame)。陷阱桢是一个与CONTEXT相似的结构,利用这个结构,可以得到所有寄存器的状态和指令寄存器所指向的产生异常的地址。我倾向于使用Compuware/Numega的SoftICE调试器来完成所有工作,但当调试陷阱桢时,WinDbg提供了更好的结构识别能力。如果只使用SoftICE,我必须手动定位先前的堆栈参数。

    假如你的电脑设置了蓝屏时的内存转储功能,那么这个文件的默认存储路径为%SystemRoot%/MEMORY.DMP。加载WinDbg并且选择“打开崩溃转储(Open Crash Dump)”加载所保存的文件。下面是由陷阱处理程序直接调用KeBugCheckEx的例子。

在加载内存转储文件后,WinDbg显示如下:




 
WinDbg显示了KeBugCheckEx是由自陷程序KiTrapOE调用的以及而且陷阱桢的地址是0x8054199C .现在就用“trap address”命令来显示陷阱桢的内容。



现在我们可以看到异常抛出时所有寄存器的状态,同时也能显示一部分的内存区域。看到指令寄存器的值为0x41414141,表明是在用户区域。现在我们可以按照自己的意愿任意改变执行流程。
这种情况下,数据是由ESP寄存器来定位的:


 
现在我们就可以利用JMP ESP,CALL ESP, PUSH ESP/RET等偏移值替换0x41414141来实现执行流程重定向,可以采用任何标准溢出技术重现漏洞溢出。
如果KeBugCheckEx是由异常处理机制引发的,陷阱桢是作为第三参数传递给KiDispatchException。在这种情况下,你需要将第三参数的地址传递给自陷命令。
当流程重定向偏移地址时,该偏移地址必须是个静态的内存地址(也就是说,在内存中的地址的不变的)。

Shell Code示例

    第一个Shell Code示例是“Kernel Loader”,允许插入到任何用户区域代码并且安全的执行,这对于执行远程Shell code和任何用户级Shell Code来说是很方便的。

    第二个示例是pure kernel.这个例子建立一个用户键盘中断处理程序来捕获所有的键盘输入消息。然后利用shell code TCPIP.SYS ICMP处理程序,让键盘缓冲区通过ICMP ECHO请求返回到远程系统。这段代码很小,利用了很少的API函数。为了完全理解下面的示例,我拷贝了相应的源代码。

The “Kernel Loader”

       有很多技术可以把代码从内核状态转换到用户状态并且执行,举个例子,你可以改变正在执行的线程的EIP,让它指向自己的代码——如果采用这个技术,正在运行的进程就会自我销毁。

    可以使用NTOSKRNL中的RtlCreateUserThread和RtlCreateUserProcess函数,这些函数会创建SMSS.EXE(唯一一个没有父进程的进程,由内核直接创建)。然而这里有两个问题:第一,他们不是导出函数;第二,是个更大的问题,他们是在NTOSKRNL的INIT区段中,这意味着在进程执行之前这两个函数就已经执行。因而需要重新映射NTOSKRNL,以及初始化一些全局变量(_MmHighestUserAddress和_NtGlobalFlag), 当然还需要找到该函数的首地址。

另外一种可行的方法是在用户域进程中创建远程线程,并且直接执行该线程。Firew0rker在他的文章中谈到过这些: http://www.phrack.org/phrack/62/p62-0x06_Kernel_Mode_Backdoors_for_Windows_NT.txt

不幸的是,这种方法也有缺陷。当执行用户级代码的时候,API函数CreateProcess可能会失败,这是由于必须通知CSRSS子系统。需要重新获取workaround并且在用户级的Shell Code中建立一个新的CONTEXT结构。

为了保持shell code尽量小,同时也为了可以插入到任意用户域代码而无需改变(译注:可移植性),上述的workaround并不是一个可行的选择。因为这种方法同样利用NTDLL的导出函数,在windows 2000以外的系统中会引发一定的问题。Windows 2000使用Ox2e中断来实现3级到0级的切换,无论在3级或是0级,都可以安全的执行。

然而,在Windows&

[1] [2] [3] [4] [5] [6] 下一页

 
【相关文章:】
没有相关文章

发表评论】【打印此文】【关闭窗口】【点击数:
★好玩的休闲小游戏★