微软JET引擎中Msrd3x代码执行漏洞分析
字数 1690 2025-08-29 08:31:42

Microsoft JET引擎Msrd3x代码执行漏洞(CVE-2019-0538)分析教学文档

漏洞概述

  • 漏洞编号: CVE-2019-0538
  • 影响组件: Windows JET引擎中的Msrd3x40.dll
  • 影响范围: Windows 7至Windows 10所有版本
  • 漏洞类型: 远程代码执行
  • 发现者: Fortinet的FortiGuard实验室研究员Honggang Ren
  • 披露时间: 2018年9月报告,2019年1月微软发布补丁

漏洞触发机制

触发方式

  1. 通过Excel触发:

    • 在Excel中使用OLEDB外部数据源加载精心构造的MDB文件
    • 文件可放置于本地或SMB共享中
  2. 通过脚本触发:

    • 在Windows 10中执行命令: cscript.exe trigger.vbs

崩溃表现

  • 崩溃发生在msrd3x40!free函数中
  • 内存处于MEM_RESERVE状态
  • 无效堆地址被释放导致崩溃

漏洞技术分析

正常流程与异常流程对比

正常MDB文件 恶意构造的MDB文件
头版本字段为1 头版本字段为0
在msjet40.dll中完成标头解密 跳过标头解密操作
不调用msrd3x40.dll 调用msrd3x40.dll!ErrIsamOpenDatabase

关键漏洞点分析

  1. 版本字段欺骗:

    • 恶意MDB文件将版本字段设为0而非正常的1
    • 导致程序跳过msjet40.dll中的标头解密操作
    • 错误地调用msrd3x40.dll中的函数
  2. RC4解密后的关键数据变化:

    • 偏移量0x42处的数据初始为0x86
    • 解密后变为0
    • 导致程序进入错误的分支路径
  3. 乘法因子生成:

    • Database::AssignUserNumber函数生成错误的密钥乘法因子0x100
    • 正常情况不应产生如此大的值
  4. 无效堆地址生成:

    • 乘法因子0x100导致目标堆地址的低位字被1覆盖
    • 生成无效的堆指针
    • 后续尝试释放该无效指针导致崩溃

漏洞利用链

  1. 构造特殊MDB文件(版本字段=0)
  2. 触发错误的分支路径(调用msrd3x40.dll)
  3. RC4解密后关键偏移量变为0
  4. 生成错误的乘法因子0x100
  5. 覆盖堆指针低位字
  6. 生成无效堆地址
  7. 释放无效地址导致崩溃
  8. 精心构造可实现代码执行

防护建议

  1. 官方补丁:

    • 安装微软2019年1月发布的安全更新
  2. Fortinet防护:

    • 自2018年10月12日起,Fortinet IPS解决方案已提供防护签名:
      MS.JET.Database.Engine.Msrd3x.Remote.Code.Execution
  3. 通用防护措施:

    • 限制不可信MDB文件的处理
    • 监控异常Excel/OLE DB行为
    • 实施最小权限原则

逆向工程关键点

  1. 关键函数:

    • msjet40!ErrOpenForeignDatabase+0x65
    • msrd3x40.dll!ErrIsamOpenDatabase
    • Database::AssignUserNumber
    • Database::MarkCorrupt
  2. 关键内存操作:

    • [ecx + 6c] - 存储乘法因子
    • [ecx + eax * 2 + 194h] - 被覆盖的内存位置
  3. 调试技巧:

    • 使用gflags /p /enable cscript.exe /full启用页堆调试
    • 检查内存状态是否为MEM_RESERVE

漏洞复现环境

  • 操作系统: Windows 7至Windows 10未打补丁版本
  • 调试工具: WinDbg, GFlags
  • 触发文件: 精心构造的MDB文件
  • 触发方式: Excel或cscript.exe

总结

该漏洞利用Windows JET引擎对MDB文件版本检查的缺陷,通过精心构造的文件头引导程序进入错误处理路径,最终导致堆损坏和可能的代码执行。漏洞的根本原因在于版本字段欺骗导致程序采取错误分支,结合后续解密和内存操作中的缺陷,形成了完整的利用链。

Microsoft JET引擎Msrd3x代码执行漏洞(CVE-2019-0538)分析教学文档 漏洞概述 漏洞编号 : CVE-2019-0538 影响组件 : Windows JET引擎中的Msrd3x40.dll 影响范围 : Windows 7至Windows 10所有版本 漏洞类型 : 远程代码执行 发现者 : Fortinet的FortiGuard实验室研究员Honggang Ren 披露时间 : 2018年9月报告,2019年1月微软发布补丁 漏洞触发机制 触发方式 通过Excel触发 : 在Excel中使用OLEDB外部数据源加载精心构造的MDB文件 文件可放置于本地或SMB共享中 通过脚本触发 : 在Windows 10中执行命令: cscript.exe trigger.vbs 崩溃表现 崩溃发生在 msrd3x40!free 函数中 内存处于 MEM_RESERVE 状态 无效堆地址被释放导致崩溃 漏洞技术分析 正常流程与异常流程对比 | 正常MDB文件 | 恶意构造的MDB文件 | |------------|------------------| | 头版本字段为1 | 头版本字段为0 | | 在msjet40.dll中完成标头解密 | 跳过标头解密操作 | | 不调用msrd3x40.dll | 调用msrd3x40.dll !ErrIsamOpenDatabase | 关键漏洞点分析 版本字段欺骗 : 恶意MDB文件将版本字段设为0而非正常的1 导致程序跳过msjet40.dll中的标头解密操作 错误地调用msrd3x40.dll中的函数 RC4解密后的关键数据变化 : 偏移量0x42处的数据初始为0x86 解密后变为0 导致程序进入错误的分支路径 乘法因子生成 : Database::AssignUserNumber 函数生成错误的密钥乘法因子0x100 正常情况不应产生如此大的值 无效堆地址生成 : 乘法因子0x100导致目标堆地址的低位字被1覆盖 生成无效的堆指针 后续尝试释放该无效指针导致崩溃 漏洞利用链 构造特殊MDB文件(版本字段=0) 触发错误的分支路径(调用msrd3x40.dll) RC4解密后关键偏移量变为0 生成错误的乘法因子0x100 覆盖堆指针低位字 生成无效堆地址 释放无效地址导致崩溃 精心构造可实现代码执行 防护建议 官方补丁 : 安装微软2019年1月发布的安全更新 Fortinet防护 : 自2018年10月12日起,Fortinet IPS解决方案已提供防护签名: MS.JET.Database.Engine.Msrd3x.Remote.Code.Execution 通用防护措施 : 限制不可信MDB文件的处理 监控异常Excel/OLE DB行为 实施最小权限原则 逆向工程关键点 关键函数 : msjet40!ErrOpenForeignDatabase+0x65 msrd3x40.dll!ErrIsamOpenDatabase Database::AssignUserNumber Database::MarkCorrupt 关键内存操作 : [ecx + 6c] - 存储乘法因子 [ecx + eax * 2 + 194h] - 被覆盖的内存位置 调试技巧 : 使用 gflags /p /enable cscript.exe /full 启用页堆调试 检查内存状态是否为 MEM_RESERVE 漏洞复现环境 操作系统: Windows 7至Windows 10未打补丁版本 调试工具: WinDbg, GFlags 触发文件: 精心构造的MDB文件 触发方式: Excel或cscript.exe 总结 该漏洞利用Windows JET引擎对MDB文件版本检查的缺陷,通过精心构造的文件头引导程序进入错误处理路径,最终导致堆损坏和可能的代码执行。漏洞的根本原因在于版本字段欺骗导致程序采取错误分支,结合后续解密和内存操作中的缺陷,形成了完整的利用链。