http://bbs.pediy.com/thread-215974.htm
Microsoft XML Core Services 缓冲区溢出漏洞
(CVE-2012-1889 )
漏洞分析报告
软件名称 : Microsoft Internet Explorer
软件版本 : 6.0\8.0
漏洞模块 : msxml3.dll
模块版本 : -
编译日期 : 2008-04-14
操作系统 : Windows XP/7
漏洞编号 : CVE-2012-1889
危害等级 :高危
漏洞类型 :缓冲区溢出
威胁类型 :远程
分析人: PineCone
2017 年 7 月 12 日
Microsoft XML Core Services(MSXML) 是一组用于用 Jscript 、 VBScript 、 Microsoft 开发工具编写构筑基于 XML 的 Windows-native 应用的服务。
Microsoft XML Core Services 3.0~6.0 版本中存在漏洞,该漏洞源于访问未初始化内存的位置。远程攻击者可借助特制的 web 站点利用该漏洞执行任意代码或导致拒绝服务。
1. 运行收集到的 PoC_1(见附件) ,在 Windows XP+IE6 的环境下用 Windbg 附加调试,程序运行至崩溃,中断处如图:
可见导致崩溃的 [ecx+18h] 中的 ecx 经过 eax 来自 [ebp-14h] 。
推测问题由 mov eax,dword ptr[ebp-14h] 产生。
2. 运行收集到的 PoC_2(见附件) ,在 Windows XP+IE6 的环境下用 Windbg 附加调试,程序运行至崩溃,中断处如图:
可见此时 eax 中为 0x0c0c0c0c, 即 ebp-14h 中为 0x0c0c0c0c
推测攻击数据被错误的当成了类对象
3. 结合 PoC_1 与 PoC_2 代码可知 PoC 用作方法调用 definition 函数,而 MSDN 中 definition 作为属性使用,作为属性的成员当作了方法使用因此触发了漏洞。因为 PoC_2 中提供了将 eax 变为 0x0c0c0c0c 的思路,确定可以使用堆喷射技术完成攻击。
4. 制作 PoC 利用漏洞。
微软在 IE8.0 中使用了 DEP 保护的技术,我们需要使用精准堆喷射以及 Ret2Libc 技术来完成攻击,本实验中一些 windbg 的指令需要 mona2 插件。
数据执行保护 (Data Execution Prevention,DEP) 是微软从 Windows XP SP2 开始加入的一种非常强悍的安全保护技术 , 它通过设置内存页的 NX/XD 标志位,来防止堆控件、栈空间的代码执行。
由于 IE 8.0 对堆喷射做了一定的限制,采用直接字符串赋值方式会被禁止,因此我们要将堆喷射时的代码做一些修改。
修改前
修改后
本次使用 Ret2Libc 技术绕过 DEP 检测
由于绝大多数的 x86 系统中内存的分页都是 4KB 大小 , 假如知道了一个地址距离某个内存页的起始偏移,就可以构建多个完全相同的内存块,并且在偏移位置有关键数据,以此构成精准堆喷射。
每个子数据块分为 4 部分: Padding , Ret2Libc , Payload , FillData 。
Padding 为衬垫部分,由大量的滑板指令组成,填充内存页起始到关键数据偏移,使用公式:相对偏移 =( 目标地址 -UserPtr 地址 )%0x1000/2 可得偏移为 0x5F6,UserPtr 可在 windbg 中如下图所示指令获得(需要加载符号)。
Ret2Libc 为绕过 DEP 最主要的部分,我们将使用此技术修改 0x0C0C0C0C 处内存分页的属性为可执行从而让 Payload 顺利生效,具体详情见 2.2.3 。
Payload 部分略。
FillData 为填充数据,由此部分将数据块填充到 4KB ,具体内容也是大量滑板指令。
根据前辈们的经验可知在 XP SP3+IE8 环境中,一个内存块大小为 0x40000, 并且有 0x02 的块启示与 0x21 的块结尾,故构造数据块时要在头尾预留出这两部分的大小。
2.2.3 Ret2Libc
返回到库函数执行 (Return to libc,Ret2Libc) 是指利用系统自身存在的代码 , 来调用一些可以关闭 DEP 的函数,由于整个过程我们使用的全部都是系统自身的代码,因此不存在被 DEP 阻拦的情况,当我们的代码运行完毕后, DEP 即失效,本例使用 VirtualProtect 函数修改内存页属性通过 DEP 。
首先我们需要一个可以将栈转移到我们可控内存空间的方法,我们将其称之为 StackPivot 的小构件 (Gadgets) ,例如 XCHG EAX,ESP 指令,因为我们要利用的数据在上一步精准堆喷射被存放在 0x0C0C0C0C ,而 EAX 的值也是 0x0C0C0C0CXCHG EAX,ESP 后, ESP 变为 0X0C0C0C0C ,即我们自己构筑了栈,后面的事就顺水推舟了。执行本处使用 mona 查找 XCHG EAX,ESP;RETN ,在 windbg 中输入 !py mona find -s "\x94\xc3" -m msvcrt.dll :
使用相同的方法在 msvcrt.dll 中找到 RETN 与 POP XXX 。
RETN: 0x77C17A42
POP EBP : 0x77BF398F
因为 ECX=[ECX]=EAX=[EAX]=0C0C0C0C 我们发现在溢出位置在这次构筑中无法完成攻击:
观察溢出点后发现幸好之后还有另一个可以利用的 CALL :
将栈溢出部分的数据由 0C0C0C0Ch 修改为 0C0C0C08h 使得 EAX 与 ECX 获得不同的值以避免 RETN 指令将 0C0C0C0Ch 作为返回地址。
具体构建内容如下:
2.2.4 构筑执行链
VirtualProtect 函数原型如下
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
上传的附件: