当前位置:首页 > 电脑常识 > 正文

0143分析 8090安适门户

11-20 电脑常识

4月20日,Nils Sommer在exploitdb上爆出了一枚新的Windows内核缝隙PoC。该缝隙影响所有版本的Windows操纵系统,打击者操作告成后可获得权限提升,微软在4月补丁日修复了该缝隙。 

0×01 缝隙分析

NilsSommer并没有说明该缝隙为何种类型的缝隙,咋看瓦解场景会认为是NULL Pointerdereference或者UAF缝隙,大略分析后,感受是整数溢露马脚,但是最后还是将其界说为特殊的NULL Pointerdereference缝隙。下面对缝隙成因进行简单分析。

In xxxRealDrawMenuItem

瓦解的处所是在win32k!xxxRealDrawMenuItem函数内,在windbg中检察瓦解时的内存状态:

瓦解上下文代码的IDA截图,将其定名为过程A(最后说明时会用到):

在crash之前,eax会和[ebp+arg_8]做有标记乘法,并将功效和ebx做对照,来确定是否执行crash的指令。

此时的eax为PoC中r.bottom和r.top运算后的功效,具体操纵在win32k!xxxDrawMenuBarTemp内,算法为:eax= r.bottom-r.top-1;

[ebp+arg_8]为PoC中的info.bmiHeader.biSize;

PoC给的值会让”imul eax,[ebp+arg_8]”孕育产生溢出,走向crash流程。这里看起来是由于整数溢出造成的缝隙,其实正常流程城市走这个流程的,这并不是缝隙成因地址。

所操纵的ecx从[ebp+var_28]获取,原始值为1,[ebp+var_28]本应该为DIBObject的地点,但是在为其分配内存的函数win32k!SURFMEM::bCreateDIB中,并没有为其分配内存空间,缝隙的关键在这里。

下面分析创建DIBObject掉败的原因。

In SURFMEM::bCreateDIB

SURFMEM::bCreateDIB的函数挪用栈:

xxxDrawMenuBarTemp

à GreCreateDIBitmapReal

àSURFMEM::bCreateDIB 

在SURFMEM::bCreateDIB函数内有这样一段代码,将其定名为过程B:

此时eax即是xxxRealDrawMenuItem函数中的edi,[ebp+arg_0]为PoC中的info.bmiHeader.biSize*4,凭据PoC中设定的值,两者分袂为0x7fffff69和0×274。

当两者进行乘法运算后,同样产生了溢出,但由于是无标记运算,所以edx!=0。挪用函数ULongLongAdd后,[ebp+AllocationSize+4]=edx=139h!=0,因此便走向了掉败的流程,不会为DIBObject分配内存,也导致GreCreateDIBitmapReal函数的返回值为0。 

如果未产生溢出,并且两者的乘积(+0×154)小于7FFFFFFFh, SURFMEM::bCreateDIB函数就会按照这个乘积(+0×154)为DIBObject分配一块内存。分配内存的代码在IDA中的截图:

分配告成后,会将AllocateObject的返回值作为GreCreateDIBitmapReal函数返回值,并且赋值给xxxRealDrawMenuItem 函数中的[ebp+var_28]。

0×02 补丁比拟

来看看微软是怎么来补这个缝隙的,补丁后的部分xxxRealDrawMenuItem函数代码在IDA中的截图:

可以看到,补丁后,xxxRealDrawMenuItem函数在挪用GreCreateDIBitmapReal函数后,对返回值做了查抄:如果返回值即是0,暗示创建DIBObject掉败,则不会再进入到操纵DIBObject的流程,也就是过程A中了。

0×03 可能的操作

目前还没有人果然本身的操作代码,下面对该缝隙存在的可能操作方法做一个说明。

crash处是一个对ecx进行循环操纵的代码段,循环次数为”imul eax,[ebp+arg_8]”的乘积。正常情况下是对申请的DIBObject进行操纵。

这个循环操纵中,存在一个可控的写入操纵指令,在IDA中的截图:

红框中的指令就是所说的写入操纵指令,edx虽然经历多条指令操纵后才得到,但是参预操纵的都是ecx相关内存值,因为ecx也就是零页地点的内容可控,所以edx也是可控的。

那么理论情况下,在win8之前的系统中,是可以将这条指令操纵改变为:

mov[HalDispatchTable+4],shellcodeAddress

之后用户层再触发一下就完成了提权。

0×04 其他

颠末深入分析后,要触发缝隙,r.bottom、r.top和info.bmiHeader.biWidth满足必然的约束就行了,不必然需要和作者给出PoC的数值完全不异。r.bottom、r.top和info.bmiHeader.biWidth的值能满足下面两个条件就可以导致crash:

1.过程B分配DIBObject掉败。

2.过程A走向crash流程。

过程B和过程A要满足这两个条件,具体情况如下。

过程B

1. 过程B未产生溢出,并且乘积后的值 < 0x7FFFFFFF,造成AllocateObject挪用掉败。

2.过程B未产生溢出,并且乘积后的值 > 0x7FFFFFFF,不走挪用AllocateObject的流程。

3.过程B产生溢出,不走挪用AllocateObject的流程。

过程A

1.未溢出。

2.溢出后的功效为负数,并且转变sf位为1(有标记数对照)。

温馨提示: 本文由杰米博客推荐,转载请保留链接: https://www.jmwww.net/file/pc/12616.html

博客主人杰米WWW
杰米博客,为大家提供seo以及it方面技巧喜欢的朋友收藏哦!
  • 11365文章总数
  • 1378073访问次数
  • 建站天数
  •