Microsoft Office内存损坏漏洞(CVE-2017-11882)实战
作者:网友投稿 时间:2018-02-25 21:38
本文分析了CVE-2017-11882 poc样本的文件结构,在分析poc样本时介绍了rtf文件、Equation Native数据结构、MTEF流数据结构、FONT记录数据结构的基本知识。在分析完poc样本后,通过windbg、IDA分析、调试了漏洞。在漏洞调试分析的基础上给出了漏洞exploit编写过程。通过poc样本分析、漏洞调试、exploit编写等过程掌握了漏洞详情,提取了漏洞特征。根据漏洞特征及poc样本网络传输中的IP数据包分析,编写了针对CVE-2017-11882的漏洞利用入侵检测规则。在编写规则中总结了2条漏洞利用入侵检测规则的编写准则。
1.漏洞介绍CVE-2017-11882漏洞在office处理公式时触发。Office公式为OLE对象,office在处理公式时会自动调用模块EQNEDT32.EXE来处理这类OLE对象。在EQNEDT32.EXE程序中,存在处理公式对象的字体tag时对字体名长度未验证的漏洞。漏洞导致栈溢出,可以覆盖函数的返回地址,从而执行恶意代码。
2. 漏洞分析 2.1.工具生成POC样本python2017-11882_Generator.py -x “cmd /c calc” -o test.rtf
python2017-11882_Generator.py下载地址:https://github.com/BlackMathIT/2017-11882_Generator

RTF文件由未格式化本文、控制字、控制符和组组成,包含文件头和文档格式为:{ <header><document>}两部分。
控制字最长32个字符。控制字的使用格式如下:
\字母序列<分隔符>
分隔符为:空格、数字、连接符“-”、任何非字母和数字的其他字符(此时字符不是控制字的部分)。
控制字一般不含大写字母,但有部分例外。
控制符由一个反斜线\跟随单个非字母字符组成。例如,\~代表一个不换行空格。控制符不需要分隔符。
组由包括在一对大括号“{}”中的文本、控制字或控制符组成。左扩号“{”表示组的开始,右扩号“}”表示组的结束。
字体、文件、格式、屏幕颜色、校订标记,以及摘要信息组、文档格式属性,一定要在文件的第一纯文本字符之前,字体组在格式组之前。这些组形成RTF的文件头。
2.2.1. 文件头<header>
RTF文件必须紧跟着左括号之后标明RTF版本号,RTF头部需要指定支持的字符集,字符集控制字必须在任何纯文本或任何表控制字之前。
RTF头内容:
RTF版本,\rtfN,如:\rtf1
字符集<charset>,如:\ansi
UnicodeRTF ,用来执行Unicode向ANSI转换的ANSI代码页。如:\ansicpg1252
默认字体<deffont>,默认字体号\deff? ,如:\deff0
字体表<fonttbl>
文件表<filetbl>?
颜色表<colortbl>?
样式表<stylesheet>?
编目表<listtables>?
编目表{ \*\listtable }
编目替换表{ \*\listoverridetable }
段落组属性{ \*\pgptbl }
跟踪修订<revtbl>?
RSID表<rsidtable>?
生成器信息<generator>?
2.2.1.1. AnsicpgN定义字体
如Ansicpg1252表示字体是拉丁文,1252是拉丁文字体在ansi中的页码。
字体对应页码表:
·874 (ANSI/OEM -泰文)
·932 (ANSI/OEM -日文Shift-JIS)
·936 (ANSI/OEM -简体中文GBK)
·949 (ANSI/OEM -韩文)
·950 (ANSI/OEM -繁体中文Big5)
·1250 (ANSI -中欧)
·1251 (ANSI -西里尔文)
·1252 (ANSI -拉丁文)
·1253 (ANSI -希腊文)
·1254 (ANSI -土耳其文)
·1255 (ANSI -希伯来文)
·1256 (ANSI -阿拉伯文)
·1257 (ANSI -波罗的海文)
·1258 (ANSI/OEM -越南)
2.2.1.2. 生成器(\*\generator)
为文档加上戳记,包括其名称、版本、生成号等。生成器区域使用如下语法:
‘{‘ \*\generator <name> ‘;’ ‘}’,
其中<name> #PCDATA,可以包括:程序名、版本、生成号以及其他与生成程序相关的能够列在这里的任何信息。该区域中只允许使用ASCII文本。
生成器例子:
{\*\generator Riched20 6.3.9600}2.2.2. 文档区<document>
2.2.2.1. 文档区的语法
<document> <info>? <docfmt>* <section>+文档区由信息组、文档格式属性、节文本、段落文本、字符文本、对象、图片等组成
2.2.2.2. 信息组语法
信息组(可以没有),控制字\info引入了信息组,信息组包含了文档的相关信息。这些信息包括:标题、作者、关键字、注释和文件的其它特定信息。
2.2.2.3. 文档格式属性
在信息组的后面(可以没有),是一些文档格式控制字(在文档区语法描述中使用<docfmt>描述)。这些控制字指明了文档的属性,必须要在文档的第一个纯文本字符之前。
如:\deflang1033(定义文档使用的默认语言),\viewkind4(定义文档视图模式)
2.2.2.4. 段落文本属性
段落有两种类型:纯文本和表。如:\pard\sa200\sl276\slmult1\f0\fs22\lang9
2.2.2.5. 字符文本属性
这些属性指定字体(字符)格式,重置文档语言。如:\f0\fs22\lang9
2.2.2.6. 对象
对象是一个包含数据和一个结果的目标引用。当对象为一个OLE嵌入对象或者链接对象时,其数据部分采用OLESaveToStream函数生成的结构体。
如:\object\objemb,指定对象为嵌入式ole对象。
\objupdate,强制对象在显示前更新。
\objw,对象宽度
Objh,对象高度
2.3.EquationNative结构基础知识Equation Native流数据 = EQNOLEFILEHDR + MTEFData,其中
MTEFData = MTEFheader + MTEF Byte Stream
EQNOLEFILEHDR头结构(共28字节)
struct EQNOLEFILEHDR{
WORD cbHdr; // 格式头长度,固定为0x1C(28字节)。
DWORD version; // 固定为0x00020000。
WORD cf; // 该公式对象的剪贴板格式。
DWORD cbObject; // MTEF数据的长度,不包括头部。
DWORD reserved1; // 未公开
DWORD reserved2; // 未公开
DWORD reserved3; // 未公开
DWORD reserved4; // 未公开
};
MTEF header结构
struct MTEF_HEADER {
BYTE bMtefVersion; // MTEF版本号,一般为0x03
BYTE bPlatform; // 系统生成平台,0x00为Mac生成,0x01为Windows生成
BYTE bProduct; // 软件生成平台,0x00为MathType生成,0x01为公式编辑器生成
BYTE bProductVersion; // 产品主版本号
BYTE bProductSebVersion; // 产品副版本号
};
MTEF Byte Stream的结构
initial SIZE record:记录的初始SIZE
PILE or LINE record:一个PILE或LINE record tag
contents of PILE or LINE :PILE或LINE的实际内容,往往是一个其他记录(记录见下表)
END record:记录结束
各种record的类别如下:



