cve-2016-7193:wwlib 模块解析 dfrxst 控制字堆数据结构溢出

本文详细解析了CVE-2016-7193漏洞,涉及Office的wwlib模块,通过堆溢出实现APT攻击。文章介绍了漏洞原理、利用条件、分析过程,以及微软发布的补丁。操作环境主要集中在Windows10和Office2016版本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

操作环境

  • 系统:Win10 1607
  • 软件版本:Office2016 16.0.4266.1003
  • poc:cve-2016-7193.rtf
  • 工具:Process Monitor、windbg、IDA

分析

  • 文件格式分析:样本经过博主进行简化,经过控制字运行分开运行之后发现 \dfrxst9(具有长度字节的 Unicode 字符数组)和 *\shpinst(RTF 用于绘图对象)控制字是触发漏洞的原因之一
    在这里插入图片描述

原因分析

崩溃点分析

  • 开启堆调试载入文档后引发异常,可见 eax 指向了未知地址导致了异常
    在这里插入图片描述
  • 从 IDA 分析崩溃点可以看出 mov ecx, [eax] 是取出了对象的虚表,并且调用了虚表 +1C 位置的函数
    在这里插入图片描述

逆向分析(基地址:0x66730000)

  • 经过逆向分析之后,得出 wwlib 在解析包含数字的 dfrxst 控制字时会在 wwlib!PTLS7::FsUpdateFinitePage+0x6d181(66a16efc) 地址上调用 sub_66a16c81 函数对数字进行处理。例如 langfe1024 控制字的数字为 1024,ASCII 为 0x31 0x30 0x32 0x34,在此基础上减去 0x30 得出 1 0 2 4,然后经过 ((((1) * a) * a + 2) * a + 4) 公式计算得出为 0x400,暂时称这个值为 “dfrxst 控制字后数字运算值”
    在这里插入图片描述
  • 在 wwlib!PTLS7::FsUpdateFinitePage+0x7a9c0(66A2473B) 地址上将 “dfrxst 控制字后数字运算值” 循环写入 v126 + v13 + 0x8FA0 这个地址,暂时将这个地址中的数据结构称为 “dfrxst 控制字后数字运算值数组”
    在这里插入图片描述
  • 在 wwlib!PTLS7::FsUpdateFinitePage+0x74113(66a1de8e) 地址中将 v257[0x8FC4] 传入 sub_669e393f 函数,v257 变量中的值实际上指向上面的 v126 + v13 计算后得出的地址
    在这里插入图片描述
  • 在 wwlib!PTLS7::FsUpdateFinitePage+0x39dc0(669E3B3B) 地址中会将之前 v257[0x8FC4] 往后的数据写入到 TLS(0x1e) 中指定的地址,方便后面取出
    在这里插入图片描述
  • 在 wwlib!PTLS7::FsDestroySubpageBreakRecord+0x10920(669477DD) 地址中会取出上面 TLS(0x1e) 的地址
    在这里插入图片描述
  • 在 wwlib!PTLS7::FsDestroySubpageBreakRecord+0xbfdd(66942E9A) 地址上会取出 “dfrxst 控制字后数字运算值数组” +0x24 偏移的数据,调试时值为 0x09c00c0c
    在这里插入图片描述
  • 然后调用 MSO_557 函数取出 0x09c00c0c + 0x48 地址的值,因为没有堆喷射,所以值为 0x00000000,最后在调用 mov ecx, [eax] 指令从 0x00000000 地址取值时崩溃
    在这里插入图片描述

根本原因

  • 由于 wwlib!PTLS7::FsUpdateFinitePage+0x7a9c0(66A2473B) 地址上循环调用 swtich case 138 分支将 “dfrxst 控制字后数字运算值” 写入 v126 + v13 + 0x8FA0 地址时并没有控制循环的次数,导致只要存在足够多的带数字的控制字,就会造成堆中的数据溢出
    在这里插入图片描述
  • 以下为写入前的 “dfrxst 控制字后数字运算值数组” 结构,可以看到 +0x24 的地方是一个数据结构,值为 0x56f30f90
56bc1450  00000009 00000000 00000000 00000000
56bc1460  00000000 00000000 00000000 00000000
56bc1470  00000001 56f30f90 00000000 00000000
56bc1480  00000000 00000000 00000000 00000000
56bc1490  00000000 00000000 00000000 00000000
56bc14a0  00000000 00000000 00000000 00000000
56bc14b0  00000000 00000000 00000000 00000000
56bc14c0  56f30f90 00000000 00000000 00000001
  • 在持续写入之后会造成溢出,可以看出 0x56f30f90 变成了 0x09c00c0c。至于为什么 +0x20 的地方没有变化,因为这是一个 int 变量,用于统计写入的字节大小,并且在写入之后进行更新
56bc1450  0c0cc009 0c09c00c 0c09c00c 0c09c00d
56bc1460  0bc0090c 15172018 09c00c0c 200c09c0
56bc1470  00000028 09c00c0c 00000000 00000000
56bc1480  00000000 00000000 00000000 00000000
56bc1490  00000000 00000000 00000000 00000000
56bc14a0  00000000 00000000 00000000 00000000
56bc14b0  00000000 00000000 00000000 00000000
56bc14c0  56f30f90 00000000 00000000 00000001

构建与利用

构建流程

  • 只要存在足够多的 dfrxst[数字] 控制字就会造成堆中数据溢出

利用姿势

  • 使用堆喷射技术将载荷喷射到 0x09c00c0c + 0x48 地址左右就可以进行利用,也可以手动修改 0x09c00c0c 地址

缓解

  • 补丁:https://learn.microsoft.com/en-us/security-updates/securitybulletins/2016/ms16-121

参考

  • https://paper.seebug.org/288/
  • https://bbs.kanxue.com/thread-221792.htm
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值