CVE-2017-11826:Office Open XML 标签嵌套解析混淆漏洞
\x01 前言
CVE-2017-11826据说是 360 在 2017 年 9 月底发现的一个关于 XML 格式解析的一个漏洞,之后微软在10月份发布了关于CVE-2017-11826的补丁,补丁地址:https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-11826

- 该漏洞的成因是由于在解析闭合元素时,没有对元素的完整性做出判断,导致将当前元素的嵌套关系加上
1。这样的话wwlib模块在处理闭合标签时,会错误的使用父级元素w:name属性+44的地址进行虚函数调用,攻击者通过修改w:name属性,就可以进行任意地址调用。 - 受影响的
Office版本。

\x02 调试环境
- 操作系统:Windows 7 + VMware
- 调试工具:x64dbg
- 漏洞样本:POC(提取码:lxx6)
\x03 调试分析
- 从
GitHub上下载关于CVE-2017-11826漏洞的文件夹,解压后发现包括解压过的docx文件、README文件、俄文文档,俄文文档没有仔细看,好像是关于漏洞利用的。

- 包含漏洞的
XML文件为document.xml,文件在word路径下。打开document.xml文件,分析后发现<w:font>标签使用了</o:idmap>标签进行闭合,而<w:font>标签的w:name属性有点奇怪,可能是用于控制某一个地址的值。

- 将解压过的
docx文档重新压缩,之后使用注册表附加调试器准备调试。

- 附加完成之后打开含有漏洞的文档,运行后触发异常,其中
call [ecx+4]指令是利用虚函数表调用虚函数,而ecx为虚函数表指针,通过wwlib.41249DA0函数返回。

- 查看堆栈调用,发现用于处理
XML格式的msxml模块,msxml模块通过间接调用wwlib模块去协助解析XML格式。暂且将wwlib.3161309E函数定为漏洞函数。

- 对漏洞函数下记录断点后查看日志内容,发现漏洞函数被调用了
6次,结合document.xml文件中的标签元素分析漏洞函数很有可能是用于解析元素标签的,至于解析的是什么,目前还不清楚。


- 选取最后一次调用漏洞函数的
esp下条件断点,分析漏洞函数处理流程。

- 函数断下后从传入的参数可以发现,
esi可能是储存标签信息的数据结构。

- 单步进入该函数,在如图所示的位置会取出元素的嵌套关系,此时
<o:idmap>标签已经插到了w:font标签的后面(以":"符号为分隔符)。而<w:font>标签在未闭合的情况插入了<o:idmap>标签,说明嵌套关系已经被错误的解析。

- 调试到
0x31613084地址时发现会调用wwlib.31249DA0函数,经过分析后发现该函数的返回值和异常处的虚函数表调用有关,所以进入这个函数看看。

- 通过分析发现该函数对
ecx和edx做了一些简单的计算,算法为[[ecx]+8]*edx + [[ecx]+C] + [ecx],计算结果为0x0751D140;而ecx是由esi传入,edx又等于[[esi]],所以算法变为[[esi]+8]*([[esi]]-2) + [[esi]+C] + [esi],由传入的esi控制,经过后面的分析可以得出[[esi]]其实就是当前元素的嵌套等级。

- 调用完
wwlib.31249DA0后会将[[0x0751D140+44]+44]地址的值作为虚函数表指针进行虚函数调用,进而触发异常。如图所示可以看出[0x0751D140+44]地址被覆盖成了<w:font>元素的w:name属性,所以攻击者通过修改<w:font>标签的w:name属性就可以做到调用任意地址。


- 接下来更改样本中的
document.xml文件,手动添加</w:font>闭合标签,看看是否会触发异常。

- 在漏洞函数处断下,这时的嵌套等级为 5。

- 之后通过
wwlib.31249DA0计算虚函数调用地址为0x075098F4。由于嵌套等级为5,所以计算出的结果为F4(4C*(5 - 2) + 10),之前的为140(4C*(6 - 2) + 10)。

- 虚函数调用后程序并没有触发异常。

\x04 分析 msxml 模块处理步骤
- 为了快速了解
msxml模块的处理流程,对调用堆栈中的所有msxml模块函数下记录断点,查看日志。

- 从日志中可以发现漏洞函数的调用都是通过
sub_78887830函数中的call [ebx+200]的指令实现的,但是倒数第二个漏洞函数的调用却没有经过call [ebx+200]而是直接跳到了MSO模块。

- 对倒数第二个漏洞函数下断点。断下后分析堆栈调用,发现
msxml.78887830函数中的call [ecx+20]的指令也会调用漏洞函数。


- 这样的话函数调用流程图就能分析出来了,函数调用流程如下图所示:

- 下面根据
msxml.78887830函数的最后一次调用,简单分析call [ebx+200]下的函数链调用。


- 在
msxml.78887830函数开头会将元素标签对象储存在ebx中,元素标签对象储存当前解析元素的信息,主要是元素的嵌套关系,嵌套等级等。

- 向下调试后发现
msxml.788872F7函数会获取<w:font>元素的w:name属性字符的指针。

- 而下面的
msxml.78887335函数会获取o:idmap元素字符的指针

- 获取完
o:idmap元素字符的指针后,调用msxml.788872F7函数解析o:idmap元素,在内存窗口可以看出字符指针已经指向了incer的位置,说明已经把idmap标签解析出来了。

- 之后调用
msxml.788873F0计算元素的嵌套等级,可以看出元素的嵌套等级计算出为6,但此时元素的嵌套等级依旧是5,还没有更新为6。

- 在将
[ebx+1e8]赋值给eax之后,发生了跳转,从而跳过了call [ecx+20]的调用转而进行call [ebx+200]的调用。



- 调用的函数为
mso.32751CAA,其实MSO模块的函数调用没有太大的作用,只是给后面wwlib模块的做间接处理。

- 到达
0x32751D5C的位置后执行call [ecx+20]指令调用sub_3277FAC0函数,此时esi = [esi+60]。

- 接着
sub_3277FAC0函数中会执行call [eax+10]指令调用wwlib.3127D3FB。

- 进入
wwlib.3127D3FB函数之后继续向下调试,此时[[esi+b14]]的地址中储存着元素的嵌套关系。


- 之后调用完
wwlib.3127E6B3函数后会进行一个判断,如果ebx等于0x80004001就跳转。

- 跳转完成之后调用漏洞函数,下面的流程刚刚已经分析过了。

- 根据上面调试分析的结果对其中几个位置下记录断点。查看日志可以发现
msxml.78887830函数会逐一对元素进行解析,当解析到<idmap>标签时嵌套关系为5。


- 但是在异常处嵌套关系为
6,对最后一次调用msxml.78887830函数下断点,查看嵌套关系是何时变为6的。

- 重新运行后断下,此时嵌套关系为
5。

- 当调试到
wwlib.3127D3FB函数中的0x3128E3AD位置时,嵌套关系变为了6,说明wwlib.312C6142函数更新了嵌套关系。

- 接着分析一下
w:name属性是何时被复制的。通过对漏洞异常处的分析发现w:name属性储存在元素对象中,通过对元素对象储存w:name位置下写入断点发现在WWLIB.sub_3127D3FB函数中会调用wwlib.3127E773函数复制w:name到元素对象当中,之后漏洞函数中会把w:name属性取出来进行虚函数表调用。



- 需要注意的是再上面的分析中该跳转并没有实现,也就是说这里在复制完
w:name属性之后直接返回了。而判断跳转的值是由wwlib.3127E6B3返回的,进入该函数,分析后发现在函数末尾处会将0x80004001赋值给eax,在这之前会以0x3149BFA3作为基址,以eax * 4做为偏移地址进行调用,而eax是通过[ebp-1c]传进来的,对该位置下记录断点后查看日志。

- 根据日志可以发现当
[ebp+1c]的值为0xFFFF时才会调用漏洞函数。而且解析<w:font>标签前调用一次,解析<o:idmap>标签后调用一次。

- 之后把
<o:idmap>标签删除,再对比日志信息。

- 可以发现只有在
<w:font>标签解析前才会将此值设置为0xFFFF,所以这一个值可能是用于判断元素是否闭合。

\x05 总结
- 当
msxml.78887830函数解析到<w:font>标签时,会误以为标签已经闭合,从而将<w:font>标签的w:name属性(假如有的话)添加到对象之中,同时更新元素的嵌套关系(嵌套关系变为6),导致最后使用call [ecx+4]进行虚函数表调用时虚表指针被错误的覆盖成了w:name属性中的数据触发了异常。


关于 CVE-2017-11826 的漏洞分析到此结束,如有错误,欢迎指正
CVE-2017-11826:Office Open XML 标签嵌套解析混淆漏洞的更多相关文章
- [Java] 解决spring的xml标签内不能自由增加说明的难题,方便调试、部署时进行批量屏蔽
作者:zyl910 以往我们想在spring的xml配置文件中增加说明文本时,只能使用xml注释(<!-- 注释 -->).这对于"调试.部署时想批量屏蔽部分bean" ...
- Freemarker的初次使用之FTL标签嵌套与map的使用
入职第二周了,在熟悉了公司自动化测试脚本的编写(使用什么数据库,使用哪种语言,框架带了哪些方法)后,现在开始熟悉模拟器,我们把请求发到服务器1,服务器1根据请求参数处理后将结果发给模拟器,模拟器根据服 ...
- .NET使用Office Open XML导出超大数量数据到 Excel
我相信很多人在做项目的都碰到过Excel数据导出的需求,我从最开始使用最原始的HTML拼接(将需要导出的数据拼接成TABLE标签)到后来happy的使用开源的NPOI, EPPlus等开源组件导出EX ...
- [转] Spring4.3.x 浅析xml配置的解析过程(6)——解析context命名空间之property-placeholder和property-override标签
在上一篇解析自定义命名空间的标签中,我们已经知道解析自定义命名空间的标签需要用到NamespaceHandler接口的实现类,并且知道spring是如何获取命名空间对应的命名空间处理器对象的.因此我们 ...
- .NET使用Office Open XML导出大量数据到 Excel
我相信很多人在做项目的都碰到过Excel数据导出的需求,我从最开始使用最原始的HTML拼接(将需要导出的数据拼接成TABLE标签)到后来happy的使用开源的NPOI, EPPlus等开源组件导出EX ...
- Office Open XML导出大数据
Office Open XML导出大量数据到 Excel .NET使用Office Open XML导出大量数据到 Excel我相信很多人在做项目的都碰到过Excel数据导出的需求,我从最开始使用最原 ...
- div标签嵌套原则详解(转载)
这个也许平时人们不注意,但是非常有用,尤其是当你实在找不到原因为什么网页显示错误的时候. XHTML 的标签有许多:div.ul.li.dl.dt.dd.h1~h6.p.a.addressa.span ...
- HTML5标签嵌套规则
× 目录 [1]分类 [2]子元素 [3]总结 前面的话 在html5中,<a>元素的子元素可以是块级元素,这在以前是被认为不符合规则的.本文将详细介绍html5的标签嵌套规则 分类 ht ...
- XML标签
SQL标签库提供了创建和操作XML文档的标签. 引入语法:<%@ taglib prefix="x" uri="http://java.sun.com/jsp/js ...
随机推荐
- Java 集合框架 02
集合框架· LinkedList 和 泛型 去除ArrayList中重复字符串元素 * A:案例演示 * 需求:ArrayList去除集合中字符串的重复值(相同内容的字符串) * 思路:创建新集合方式 ...
- 2019.2-2019.3 TO-DO LIST
DP P2723 丑数 Humble Numbers(完成时间:2019.3.1) P2725 邮票 Stamps(完成时间:2019.3.1) P1021 邮票面值设计(完成时间:2019.3.1) ...
- Qt3D使用assimp加载常规模型文件
Qt3D使用assimp加载三维模型文件,assimp支持很多常规格式的三维模型格式: 其中支持导入的格式有: 3D 3DS 3MF AC AC3D ACC AMJ ASE ASK B3D BLEND ...
- Anchor-Free总结
目录 Anchor-Free综述 一. CornerNet 1.1 概述 1.2 模块介绍 1.2.1 Heatmap 1.2.2 Offset 1.2.3 Grouping Corners 1.2. ...
- 【PAT甲级】1119 Pre- and Post-order Traversals(前序后序转中序)
[题目链接] [题意] 根据二叉树的前序和后序序列,如果中序序列唯一,输出Yes,如果不唯一输出No,并输出这个中序序列. [题解] 众所周知,二叉树是不能够根据前序和中序建立的,为什么呢?首先需要明 ...
- 【博弈论】组合游戏及SG函数浅析
目录 预备知识 普通的Nim游戏 SG函数 预备知识 公平组合游戏(ICG) 若一个游戏满足: 由两名玩家交替行动: 游戏中任意时刻,合法操作集合只取决于这个局面本身: 若轮到某位选手时,若该选手无合 ...
- od快捷键
视图.查看相关: Alt+l 记录 Alt+e 可执行模块 Alt+m 内存 Alt+c cpu(反汇编视图) Ctrl+p 补丁 Alt+k 调用堆栈 Alt+b 断点 Alt+f5 设置窗口总在 ...
- SpringBoot学习笔记(四)
本文主要介绍:SpringBoot开发中如何自定义starter 1.什么是starter Starter可以理解为一个可拔插式的插件,提供一系列便利的依赖描述符,您可以获得所需的所有Spring和相 ...
- 敏捷史话(十二):你现在接触的敏捷也许是“黑暗敏捷”——Ron Jeffries
他很少提起往事,也不再提及二十年前那场引起软件行业变革的会议,他专注于当下,一直活跃在敏捷领域.八十多岁的他依然运营维护着网站和博客,是极限编程网站 XProgramming.com 的作者,该网站是 ...
- 基于k8s的集群稳定架构-转载
基于k8s的集群稳定架构-转载 前言 我司的集群时刻处于崩溃的边缘,通过近三个月的掌握,发现我司的集群不稳定的原因有以下几点: 1.发版流程不稳定 2.缺少监控平台[最重要的原因] 3.缺少日志系统 ...