您的位置:首页 > 其它

微软“WebDAV”提权漏洞(cve-2016-0051)初探

2016-03-14 16:10 627 查看
*原创作者:gongmo(聚锋实验室)

注意:本分析一切结果均在win7 x86 sp1中尝试。

1.关于cve-2016-0051

在微软的官方描述中如下:

如果 Microsoft Web 分布式创作和版本管理 (WebDAV) 客户端验证输入不当,那么其中就会存在特权提升漏洞。成功利用此漏洞的攻击者可以使用提升的特权执行任意代码。

若要利用此漏洞,攻击者首先必须登录系统。然后,攻击者可以运行一个为利用此漏洞而经特殊设计的应用程序,从而控制受影响的系统。

工作站和服务器最易受此攻击威胁。此安全更新程序通过更正 WebDAV 验证输入的方式来修复这个漏洞。

通过微软的介绍,此漏洞是一个限定系统的提权漏洞,因为此漏洞在win8或者更高的系统上是触发BSOD,而在win7及以下的系统中才能提权成功。所以微软设定此漏洞的安全等级为:中。虽然如此,我们还是应该引起重视,毕竟,可以获得管理员权限的漏洞危害性依然很大。

本文通过基础性的研究,大概的探究下了漏洞的修补前后和执行的过程,供大家参考。

2.分析验证

在2016年2月9日发布的补丁中,微软修复了此问题。补丁名称为:Windows6.1-KB3124280-x86。后来通过对比这个补丁前后,发现微软在mrxdav.sys中增添了MRxDavIsCallerPrivileged函数并且修改了DAVFastIoDeviceControl和DAVDevFcbXXXControlfile的执行过程。

下图是对比补丁前后marxdav.sys执行的过程图。(红框为补丁版本)









1)MRxDavIsCallerPrivileged函数主要通过调用SeAccessCheck函数验证进程的访问权限进行作用。这样任何通过fastio分发的函数和文件控制块控制的文件,都需要经过权限的验证,是否有足够的管理员权限执行,如若没有,则MRxDavIsCallerPrivileged函数返回false,然后调用失败的路线。




2)其次在调用的历程函数中,MrxDAVEfsControl函数增加了对传入的device_object是否为null的验证。见下图红框所示缩略图:




放大图如下:




根据IDA的分析:







上图是补丁中通过验证MRX_SRV_OPEN+0×18对象结构体否为空,若不是NULL;则验证其MRX_SRV_OPEN+0×18+0xC对象,若文件对象正常,则验证其设备对象。如若出现一个为NULL;则转入失败,最后调用RxReleaseFcbResourceInMRx释放MrxFCB。

从整个函数推导来看:传入iofcalldriver函数的device_object来自:

Device_object=rx_context+0×38+0×18+0×10(win7 sp1x86系统)










由于windbg中并没有找到此结构体,但是在windws driver kits中发现了此结构,在rxcontx.h头文件中,我们可以看到rx_context的结构体;以下是个人推导(仅对win7 sp1 x86来讲):

MRX_SRV_OPEN=rx_context+0×38;

MRX_FCB=MRX_SRV_OPEN+0×10;

暂用AAA表示此结构= MRX_SRV_OPEN+0×18;

DEVICE_OBJECT=AAA+0×10;

猜测为FILE_OBJECT=AAA+0x0C

通过windbg;我们查看到验证判断的过程device_object的过程;esi的值为rx_context结构体。MRX_SRV_OPEN是bc4381f8;结构AAA为:9920f508;如下图:请依次对应。




验证判断过程如下图所示:首先去验证AAA结构是否为空,然后依次验证AAA+0x0C;最后验证AAA+0×10,即为:DEVICE_OBJECT。




3.关于漏洞程序

在微软公布修补补丁的同时,黑客大神koczkatamas公布了漏洞源码程序。

漏洞原理:

在rdbss调用mrxdav的时候,利用rdbss!RxCreateRxContext创建了一个rx_context结构体的参数,而结构体rx_context默认的一个device_object对象初始化是null。而在内存中,null可以为0×00000000;所以只要作者精心构造一个以地址0×00000000为开头的device_object结构体,填充好MajorFunction对应函数的地址(用户的函数地址)。但是想要执行,还是需要调用IoCallDriver分发函数,而想调用到IoCallDriver分发函数,作者这里使用了NtFsControlFile作为触发进入mrxdav!MrxDAVEfsControl的条件从而调用到IoCallDriver。

所以在作者公布的源码中,申请了一块以0×00000000开头的内存;并且通过Marshal.Copy函数填写完整了device_object的结构体。如下图:





通过windbg;我们可以看到71c91150处就是shellcode的地址了。也是需要执行的地方。如下图:




例如:原函数IofCallDriver执行方式为:

driverObject->MajorFunction[irpSp->MajorFunction](DeviceObject,Irp );

修改后的函数执行为:

driverObject->shellcode(DeviceObject,Irp );

下图红框就是执行r3程序的地方。(调试的次数不一样,执行shellcode的函数地址也不同,下图shellcode的地址是:6ae91150。)这样,就从内核执行了任意r3的函数,成功将系统的Token赋值给应用程序eprocess的Token,达到提权的目的。





4.总结

通过初步漏洞分析,才发现windows的博大精深。本漏洞没有通过覆盖,溢出等方法寻找突破点,而是利用了内存中NULL可以理解为0×00000000的方式,去构造漏洞。同时应对漏洞问题时候,如何以最小的改动来换取最大的安全。微软做的这点值得我们去学习思考。

*原创作者:gongmo(聚锋实验室),转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: