扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
当流程重定向偏移地址时,该偏移地址必须是个静态的内存地址(也就是说,在内存中的地址的不变的)。
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 XP下问题就产生了,Windows XP是利用SYSENTER和SYSEXIT指令对来实现0级与3级之间的切换。如果在内核中直接调用NTDLL的导出函数,意味着蓝屏即将来临。为了解决这个问题,用于在系统服务表中查询NTOSKRNL函数的额外代码是必须的.我决定采用异步过程调用(Asynchronous Procedure Calls)方式来执行用户域Shell Code,这种方法只使用直接由NTOSKRNL导出的函数。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。