当前位置: 移动技术网 > 网络运营>安全>漏洞 > WINDOWS 7 RC 7100 GDI驱动Win32k.sys内核D.O.S漏洞

WINDOWS 7 RC 7100 GDI驱动Win32k.sys内核D.O.S漏洞

2018年03月15日  | 移动技术网网络运营  | 我要评论

感谢:iceboy发现此问题并提供dump
漏洞厂商及产品:microsoft windows 7 rc 7100 090421
存在漏洞组件:win32k.sys timestamp :49ee8dc8
存在漏洞函数:ntusergetdc/ntusergetdcex

漏洞描述:win32k.sys是windows的gdi驱动程序,包含大量复杂的图形界面处理,由于其中大量代码是从win3.1中修改过来,因此成了windows漏洞多发之地。

这个漏洞主要是因为windows 7 在其ntusergetdc/ntusergetdcex函数中(也许不仅仅是这两个函数)不正确地使用了共享临界锁,导致了任何权限下的gdi程序可以引发内核bsod,从而进行dos攻击
 

漏洞分析:
在windows vista中,在这两个函数进入前,会调用userenterusercirtsec,进入临界区,同时会将gpticurrent设置为当前线程的win32thread

userenterusercritsec的实现如下:

pwin32thread userenterusercritsec()
{

pwin32thread pwin32thread;

pwin32thread = exenterpriorityregionandacquireresourceexclusive(gpresuser);
gpticurrent = pwin32thread;
gbvalidatehandleforil = 1;
return pwin32thread;
}

exenterpriorityregionandacquireresourceshared是ntoskrnl 导出一个提供给win32k使用的共享资源锁函数,这个函数将共享锁住gpresuser这个资源,同时返回当前线程的win32thread,即 kegetcurrentthread->win32thread

同时内核函数exenterpriorityregionandacquireresourceexclusive也与其类似。
(xp则是调用keentercriticalregion后,用exacquireresourceexclusivelite锁住 gpresuser,然后用psgetcurrentthread->psgetthreadwin32thread获得当前线程 win32kthread,存放到gpticurrent)

而在windows 7 中,这两个函数进入前,改为了调用userentersharedcrit,进入共享临界区

userentrysharedcirt的实现很简单

pwin32thread entersharedcrit()
{
return exenterpriorityregionandacquireresourceshared(gpresuser);
}

可以注意到,这里并不设置gpticurrent,事实上,ntusergetdc/ntusergetdcex会将这个函数保存在寄存器中以便使用currentwin32thread中存放的数据

从关键临界转为共享临界,无疑这样的修改将提升ntusergetdc/ntusergetdcex的效率,减少了锁竞争的可能,但是在这里这样修改是错误的.

因为在共享临界中,没有修改gpticurrent,那么就很可能遇到gpticurrent非法的状态,比如遇到一个没有做psconverttoguithread的线程导致了gpticurrent为空.

win32k中有大量内部例程(经常以zzz,xxx开头),他们都认为在调用自己之前,gpticurrent是一个有效的状态。这其中就包括了xxxdestorywindow

一个bsod的例子是:ntusergetdc->getwindowdc->getdcex->spbcheckdce->spbcheckrect->spbcheckrect2->freespb

调用到freespb时,这里要释放一个spb对象了

接着就到
freespb->hmassigmentunlock->hmunlockobject->hmunlockobjectinternal->hmdestroyunlockedobject, 最终调用到了ganti表中的函数,由于这里是getwindowdc,所以将调用xxxdestroywindow,xxxdestroywindow 第一句代码就无检查引用了gpticurrent指针中的数据,自然直接导致bsod

解决方案:
等待微软更新官方补丁.

微软可能的更新手段:
牺牲效率将ntusergetdc等中的不正确共享锁替换为关键临界锁,或者将所有ntusergetdc等函数可能用到的内部函数中的gpticurrent引用去掉或换为不引用gpticurrent的其他函数

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网