无需Native Code的RCE——IE8中的写入原语利用
字数 1456 2025-08-05 08:19:22
IE8类型混淆漏洞利用技术分析
漏洞概述
CVE-2019-0752是Internet Explorer 8(及更低仿真级别)中的一个类型混淆漏洞,位于mshtml!CBase::ContextInvokeEx函数中。该漏洞允许攻击者通过精心构造的DISPATCH_PROPERTYPUTREF调用,将属性getter方法误用为putter方法,从而获得受限的write-what-where原语。
漏洞原理
IDispatchEx机制
IE8及以下版本通过IDispatchEx机制执行DOM方法和属性。为提高性能,IE为部分DOM属性和方法实现了"快速路径",通过mshtml!_FastInvokeTable中的函数指针调用。
漏洞根源
漏洞源于IDispatchEx允许两种不同的属性放置方式:
- DISPATCH_PROPERTYPUT (0x4):标量值赋值
- DISPATCH_PROPERTYPUTREF (0x8):对象引用赋值
由于代码仅检查DISPATCH_PROPERTYPUT标志,DISPATCH_PROPERTYPUTREF操作会被错误路由到_FastInvokeTable中的getter方法而非预期的putter方法。
可利用场景
分析发现三种可能的函数签名混淆情况:
- Case 1:安全,仅覆盖BSTR前4字节,无法利用
- Case 2:堆栈参数长度不匹配,进程会安全关闭
- Case 3:可利用,通过CElement::get_scrollLeft实现受限的write-what-where原语
漏洞利用技术
初始PoC
Class MyClass
End Class
Set obj = New MyClass
document.body.scrollLeft = obj ' 触发漏洞
受限写入原语
- 最大可写入值:0x001767dd
- 写入位置:任意地址
- 写入内容:scrollLeft的当前值
构建完整利用链
1. 从任意写到任意读
技术要点:
- 分配大数组(0x30000000字节)覆盖固定地址0x28281000
- 通过写入改变特定VARIANT类型(VT_BYREF | VT_I4)
- 搜索被修改的数组元素("gremlin")
- 通过4次受限写入构建完整DWORD值
2. 信息泄露
- 利用gremlin元素作为读原语
- 泄露对象地址,构建完整的内存读写能力
3. 从内存控制到代码执行
颠覆调度机制技术:
- 创建伪造的vtable,将条目替换为WinExec地址
- 准备COM对象(Scripting.Dictionary)同时作为有效ANSI命令字符串
- 精心构造对象内存布局:
- 前4字节作为vtable指针(0x28282828)和ANSI字符串"(((("
- 使用路径遍历技术("..")取消虚假路径
- 预减小的引用计数,递增后形成".exe"
- 使用PowerShell注释绕过pld指针限制
内存布局示例:
Offset 0x00: 0x28282828 // vtable指针 & "(((("
Offset 0x04: 0x199e3fd4 // 引用计数(递增后为".exe")
Offset 0x08: "powershell -c \"..." // PowerShell命令
4. 绕过CFG
- WinExec未被CFG限制
- 即使启用CFG也能成功执行
完整利用代码
' 完整利用代码示例
' 注意:实际利用代码较长,此处为简化示例
' 完整代码可在GitHub存储库找到
' 1. 触发漏洞获取写入原语
Class MyClass
End Class
' 2. 构建大数组
Dim ar1(0x30000000 / 16)
' 3. 通过多次写入构建完整地址
' 4. 搜索gremlin元素
' 5. 设置伪造vtable和WinExec
' 6. 构造恶意COM对象
' 7. 触发代码执行
防护与缓解
- 微软已发布补丁修复该漏洞(CVE-2019-0752)
- 启用增强保护模式(EPM)可限制利用效果
- 禁用VBScript可有效预防此类攻击
技术启示
- 即使只有受限的写入原语,也能构建完整利用链
- 无需传统ROP或shellcode即可实现代码执行
- 内存读写能力可颠覆系统固有机制实现攻击
- 对象内存的多用途构造技术值得关注
参考资源
- 原始漏洞报告:ZDI-19-418
- 微软安全公告:CVE-2019-0752
- GitHub PoC代码库
- James Forshaw关于路径处理和VBScript的研究