关于无驱动执行Ring0代码

关于无驱动执行Ring0代码

                                      

 

    进入Ring0的办法不外乎通过调用门或中断门,两者的实现分别需要修改GDT和IDT。GDT一般在直接内存映射范围0x80000000-0x9FFFFFFF内,直接用/Device/PhysicalMemory修改就行。这个办法已经被研究的很多了,参见WebCrazy的《Windows NT/2000/XP下不用驱动的Ring0代码实现》和crazylord的《Playing with Windows /dev/(k)mem》(p59-0x10)。IDT似乎也总是在直接映射范围内,却没见过什么文章提过用户态修改IDT进入Ring0的方法,可能是因为gidt是特权指令,需要Ring0才能执行,所以难以定位IDT。说到IDT,我们自然联想到SSDT,它也被直接映射,而且可以通过KeServiceDescriptorTable定位。WebCrazy的那篇文章开头说int 2eh有严格的参数检查,"只能严格的执行Windows NT/2000提供的服务",不知道有没考虑SSDT被修改的情况。另外,关于实现通用的虚拟地址到物理地址的转换方法,flier在《自动验证Windows NT系统服务描述表的完整性》中提到,可以从KPEB的DirectoryTableBase[0](offset=0x18)获取CR3,即当前进程页目录的物理地址,然后通过查PDE/PTE解析虚拟地址。但是,很多情况下(特别是Win2000)进程的KPEB并不位于直接内存映射范围,所以CR3也得不到。
    其实,对于内存小于512M的系统,所有的信息总是"在"直接内存映射范围内的,只不过你找不到它的位置而已。除了GDT/IDT/SSDT,还有什么"东西"一定在直接映射范围又容易定位呢?答案是系统内核本身——ntoskrnl.exe和hal.dll。如此设计想必是处于性能的考虑,因为在这个范围转换地址不用查表,效率很高。于是,我们获得了修改系统内核的能力。内核都能修改,还有什么做不到的?
    找一个不常用的系统服务例程,修改入口代码,构造一个jmp指令跳转到我们的Ring0Code(),然后调用该系统服务对应的Native API,Ring0Code就被执行了。因为Ring0Code位于用户空间,所以如果在运行期间有别的进程调用该系统服务,就会jmp到未知的地方,系统崩溃。为了增加安全系数,应该在跳转前检查当前的PID是否和Ring0Code所在进程的PID一致。如果不一致,就直接返回。当然,本来该调用的系统服务是没办法执行了。所以要找个调用失败也无伤大雅的系统服务,最好是Obsolete的。找来找去,NtVdmControl好像不错。
    与修改SSDT进入Ring0相比,修改系统服务本身更隐蔽。对照当前SSDT和ntoskrnl.exe导出的符号地址,也发现不了异常。进入Ring0是如此的容易,以后所有的木马恐怕都跑到内核去了。应该建议微软取消/Device/PhysicalMemory。
    演示代码下载: http://zzzevazzz.bokee.com/inc/Ring0Demo.rar

2005-12-02 补充:2003sp1不允许从用户态调用/Device/PhysicalMemory,所以这个办法在2003sp1上没用啦。

 

【作者: zzzevazzz】【访问统计: <script language="JavaScript" src="http://counter.blogchina.com/PageServlet?pageid=427939&blogid=78422" type="text/javascript"></script> 162】【2004年12月22日 星期三 18:51】【 加入博采】【打印

Trackback

你可以使用这个链接引用该篇文章 http://publishblog.blogchina.com/blog/tb.b?diaryID=427939

回复

 
- 评论人:mvp   2005-10-03 19:54:10   

强,支持你,icesword是我们心中永远的通,3000只鸡飞了,呵呵,别太低了,我们还剩7000只

 
- 评论人:shadow3   2005-04-20 13:28:22   

2k上/Device/PhysicalMemory还是不要取消为好,不然我的炎龙2都不能玩了

 
- 评论人:wowocock   2005-02-15 16:26:10   

NtYieldExcution里面的KiSwapThread都换的确是比较好的方法了,其实如果有能力的话,你可以把NTOSKRNL里的相关函数都换成你自己的,不更好????

 
- 评论人:zzzevazzz   2005-01-10 01:33:06   

   你真够辛苦的,我看了2000源代码就觉得从线程链表入手实在太累了。更重要的是,对IceSword完全无效。有理由相信,IceSword不是走KTEB->KPEB这条路的。
   我刚刚把knlps版本从0.4升级到1.0,因为发现了一个新的历遍KPEB的办法。与历遍句柄链表相比,算是很底层了。不过,这个办法还不够完善,等我再研究一下,看有没有与人分享的价值。
   还是那句话,创建一个进程留下的痕迹实在太多。我觉得木马应该从“不用进程”和“共享进程”(一个进程空间跑多个程序)这两方面做尝试。
   QQ我加你了。

 
- 评论人:SoBeIt   2005-01-08 11:19:10   

继续你在幻影发的贴(我的hotmail收不到幻影论坛发的信,所以至今没注册),PHIDE2的思路和我实现的方法基本很相似,只不过有一点,我连NtYieldExcution里面的KiSwapThread都换了,调用的是自己的SwapContext,连KPCR中相关位都不会出现,所以调度链表里是没啥问题了,基本不会留啥痕迹。关键就是线程的链表实在是太多了,每对付一个链表就要分析相关代码原理,并复制后修改部分函数,工程实在是浩大。从这点来讲检测确实比隐藏要EASY得多,检测的链表那么多,都检测一遍就行了。还有你有没有Q?有空聊聊,我Q是27324838

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值