Windows VBScript引擎远程执行代码漏洞 之CVE-2018-8373分析与复现
字数 1302 2025-08-18 11:37:45
CVE-2018-8373: VBScript引擎远程执行代码漏洞分析与复现指南
一、漏洞概述
漏洞ID: CVE-2018-8373
漏洞名称: Microsoft VBScript引擎远程执行代码漏洞
漏洞类型: 远程代码执行 (Use-After-Free)
威胁等级: 高危
披露时间: 2018年8月14日
受影响系统版本
- IE9: Windows Server 2008 (32/64位)
- IE10: Windows Server 2012
- IE11: 大部分版本
二、漏洞原理分析
1. 漏洞背景
VBScript引擎在处理内存中对象时存在Use-After-Free漏洞,攻击者可通过精心构造的脚本在当前用户上下文中执行任意代码。成功利用此漏洞的攻击者可获得与当前用户相同的权限。
2. 技术细节
漏洞核心在于VBScript引擎对数组对象的重置操作(ReDim)处理不当,导致内存释放后仍被引用。
关键流程:
- 创建包含数组的类对象
- 初始化时分配数组内存
- 通过属性访问触发数组重置
- 原始数组内存被释放但引用仍保留
- 后续操作使用已释放的内存导致UAF
3. 漏洞触发机制
Class MyClass
Private array()
Private Sub Class_Initialize()
ReDim array(2) ' 初始分配数组
End Sub
Public Default Property Get P()
ReDim Preserve array(1) ' 重置数组,释放原内存
Set P = Me
End Property
End Class
Set cls = New MyClass
cls.array(2) = cls ' 触发UAF
三、漏洞复现环境
1. 测试环境
- 操作系统: Windows 7 (32/64位)
- IE版本: IE10
- 调试工具: Windbg
2. 所需资源
- EXP代码: GitHub - B1eed/VulRec
- 样本分析工具: IDA Pro
四、漏洞调试分析
1. 关键函数调用栈
vbscript!CScriptRunTime::RunNoEH
vbscript!VBScriptClass::Create
vbscript!VBScriptClass::InitializeClass
vbscript!CScriptEntryPoint::Call
2. 内存操作关键点
-
数组创建:
vbscript!MakeArray创建初始数组- 保存数组元素地址到栈(如0x12ae6ff0)
-
数组重置:
RedimPreserveArray调用SafeArrayRedim- 原pvData(0x12ae6fd0)被释放
- 新pvData(0x0818afe0)被分配
-
UAF触发:
- 栈上保留的旧地址(0x12ae6ff0)被后续使用
- 访问已释放内存导致崩溃
3. EXP利用技术
-
内存布局操控:
- 使用两个数组(array1和array2)
- 释放array1.pvData后让array2重用该内存
- 修改array2的SAFEARRAYBOUND结构,将长度设为0x0FFFFFFF
-
任意内存读写:
- 通过混淆array(index_vul)(index_a+n,0)和array(index_b)(0,n)
- 将variant类型在字符串和长整型间转换
- 获取可读写内存区域(util_mem)
-
Shellcode执行:
- 伪造CONTEXT结构
- 通过ROP链执行最终payload
- 典型利用结果: 弹出计算器(calc.exe)
五、防护措施
1. 官方补丁
微软已于2018年8月14日发布安全更新,建议用户及时安装。
2. 缓解措施
- 禁用VBScript执行
- 启用增强的IE保护模式
- 使用EMET等缓解工具
六、参考资源
- TrendMicro分析报告
- 微软安全公告
- 四维创智漏洞分析报告
附录:关键数据结构
SAFEARRAY结构
typedef struct tagSAFEARRAY {
USHORT cDims; // 数组维度
USHORT fFeatures; // 特性标志
ULONG cbElements; // 元素大小
ULONG cLocks; // 锁计数
PVOID pvData; // 数据指针
SAFEARRAYBOUND rgsabound[1]; // 维度信息
} SAFEARRAY;
SAFEARRAYBOUND结构
typedef struct tagSAFEARRAYBOUND {
ULONG cElements; // 元素数量
LONG lLbound; // 下界
} SAFEARRAYBOUND;