欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

从MS16-098看Windows 8.1内核漏洞利用

来源:本站整理 作者:佚名 时间:2017-01-11 TAG: 我要投稿

在我刚开始接触内核漏洞时我没有任何有关内核的经验,更不用说去利用内核漏洞了,但我总是对于逆向工程和漏洞利用技术非常感兴趣。
最初,我的想法很简单:找到一个目前还没有可用exploit的可利用漏洞的补丁,从它开始我的逆向工程以及利用的旅途。这篇文章里谈及的漏洞不是我的最早选的那个:那个测试失败了。这实际上是我的第二选择,我花费了4个月的时间来了解有关这个漏洞的一切。
我希望这篇博客可以帮到那些渴望了解逆向工程和exploit开发的人。这是一个漫长的过程,而我又是一个内核exploit开发方面的新手,所以我希望你在阅读这篇文章时能够保持耐心。
使用的工具
Expand.exe (用于MSU文件)
Virtual KD http://virtualkd.sysprogs.org/(他们说自己比正常的内核调试要快上45倍是真的)
Windbg (kd)
IDA professional. https://www.hex-rays.com/products/ida/
Zynamics BinDiff IDA plugin. https://www.zynamics.com/bindiff.html
Expand.exe的使用
Expand.exe可以用来从微软更新文件(MSU)和CAB文件中提取文件。
使用以下命令更新和提取CAB文件到指定目录:
Expand.exe -F:* [PATH TO MSU] [PATH TO EXTRACT TO]
Expand.exe -F:* [PATH TO EXTRACTED CAB] [PATH TO EXTRACT TO]

如果命令后面接地址,会根据符号定义的结构进行dump

!pool,!poolfind和!poolused命令在我分析内核池溢出,进行内核池风水时帮了我很多。
一些有用的例子:
要dump指定地址的内核池页面布局,我们可以使用以下命令:

kd> !poolused [POOLTYPE] [POOLTAG]

要检索指定池类型中的指定池标记的对象的分配数量:

kd> !poolused [POOLTYPE] [POOLTAG]

要为指定的池标记搜索提供的池类型的完整分配的内核池地址空间。

kd> !poolfind [POOLTAG] [POOLTYPE]

Windbg使用技巧
相比其他调试器我个人更喜欢Windbg,因为它支持一些很有用的命令,特别是对于内核调试来说。

kd> dt [OBJECT SYMBOL NAME] [ADDR]
dt命令使用符号表定义的结构来dump内存,这在分析对象时非常有用,并且可以在对象的符号已导出时了解一些特殊的情况。
使用这个命令时如果不加地址那么会直接显示这个对象的结构。例如,要查看EPROCESS对象的结构,我们可以使用以下命令。

通过补丁对比来了解漏洞原理
下载好更新文件,我们打开后发现被修改了的文件是win32k.sys,版本是6.3.9600.18405。当与其旧版本6.3.9600.17393进行二进制对比时,我们使用的是IDA的Zynamics BinDiff插件。可以发现一个发生了更改的有趣函数的相似性评级是0.98。存在漏洞的函数是win32k!bFill。下面是两个版本之中的区别。

diff快速的展示出了一个整数溢出漏洞是如何通过加入一个UlongMult3函数来修补的,这个函数通过相乘来检测整数溢出。如果结果溢出了对象类型(即ULONG),则返回错误“INTSAFE_E_ARITHMETIC_OVERFLOW”。
这个函数被添加在调用PALLOCMEM2之前,PALLOCMEM2使用了一个经过检查的参数[rsp + Size]。这确认了这个整数溢出将导致分配小尺寸的对象; 那么问题是——这个值可以被用户通过某种方式控制吗?
当面临一个复杂问题的时候,建议先将它分解为更小的问题。 因为内核漏洞利用是一个大问题,所以一步一步进行似乎是一种好方法。步骤如下:
1.击中存在漏洞的函数
2.控制分配的大小
3.内核内存池(pool)Feng Shui技术
4.利用GDI位图对象(Bitmap GDI objects)
5.分析并且控制溢出
6.修复溢出的头部
7.从SYSTEM进程的内核进程对象(EPROCESS)中偷取表示权限的Token
8.成功得到SYSTEM权限
Step 1 –触发漏洞函数
首先,我们需要了解如何通过查看IDA中的函数定义来击中漏洞函数。可以看出,该函数在EPATHOBJ上起作用,并且函数名“bFill”说明它与填充路径有关。通过用谷歌搜索“msdn路径填充”,我得到了BeginPath函数和示例程序。

bFill@(struct EPATHOBJ *@, struct _RECTL *@, unsigned __int32@, void (__stdcall *)(struct _RECTL *, unsigned __int32, void *)@, void *)
理论上来说,如果我们使用示例中的代码,它应该会击中漏洞函数?
// Get Device context of desktop hwnd
hdc = GetDC(NULL);
//begin the drawing path
BeginPath(hdc);
// draw a line between the supplied points.

[1] [2] [3] [4] [5] [6] [7]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载