殊途同归的CVE-2012-0774 TrueType字体整数溢出漏洞分析

1. 前言

官方的漏洞通报中,关于这个漏洞的信息其实很少:

Integer overflow in Adobe Reader and Acrobat 9.x before 9.5.1 and 10.x
before 10.1.3 allows attackers to execute arbitrary code via a crafted
TrueType font.

只有几个关键点:构造的TTF文件,Adobe Reader版本,整数溢出漏洞。

因为这是一个很老的漏洞,网上能搜到的很多分析文章都是基于《漏洞战争》这本书完成的,并且其中的大多数只是在进行书中内容的复述。在阅读书中内容的过程中,作者提到使用TrueType Font Analyzer对ttf文件进行解析时出错,由此判断问题出现在glyf表中。虽然我找到了这个工具,但实在是太小众了,是一个日本博客中提供的,而用010editor对TTF文件进行解析的过程中没有得到什么有用的输出信息。所以漏洞分析的一开始,最困扰我的就是,如果没有《漏洞战争》这本书,我要如何确定异常数据的位置。【网络安全学习攻略

以下的分析内容有些做的其实是无用功,但是体现了针对该漏洞我的整个思考思路以及分析流程,因此全部保留下来。

2. 文件格式分析理解

2.1 利用010editor初步分析TTF文件结构

如果不看书,我能想到的就是用010editor打开TTF文件。

使用PdfStreamDumper将poc.pdf中的TTF文件提取出来(之前分析过一次Adobe Reader中的字体漏洞,所以知道该怎么做),命名为poc.ttf,用010editor打开。软件自动用Template进行解析,Output中显示:

Executing template  'C:\Users\test\Documents\SweetScape\010 Templates\Repository\TTF.bt'   on  'D:\Myfiles\vul_study\ldzz\2012-0774\poc.ttf' ...
* WARNING Line  158 : Variable  'glyphIdArray'   not   generated since array size  is   zero.

双击这个警告信息,会直接打开用于解析TTF文件的bt文件,定位到出现问题的结构体中:

typedef struct tcmap_format4 {
   
     cmap_subtable  =   FTell();
     USHORT  format ;     / /   Format   number  is   set   to  4. 
     USHORT length;     / /   This  is   the length  in   bytes of the subtable. 
     USHORT language;     / /   Please see  "Note on the language field in 'cmap' subtables"   in   this document.
     USHORT segCountX2;     / /    2   x segCount.
     USHORT searchRange;     / /    2   x ( 2 * * floor(log2(segCount)))
     USHORT entrySelector;     / /    log2(searchRange / 2 )
     USHORT rangeShift;     / /    2   x segCount  -   searchRange
     USHORT endCount[segCountX2  /   2 ];     / /   End characterCode  for   each segment, last = 0xFFFF .
     USHORT reservedPad;     / /   Set   to  0.
     USHORT startCount[segCountX2  /   2 ];     / /   Start character code  for   each segment.
     SHORT idDelta[segCountX2  /   2 ];     / /   Delta  for   all   character codes  in   segment.
     USHORT idRangeOffset[segCountX2  /   2 ];     / /   Offsets into glyphIdArray  or   0
     USHORT glyphIdArray[(length - (FTell() - cmap_subtable)) / 2   ];     / /   Glyph index array (arbitrary length) !!!就是这里出现了问题!!!
};

那么为什么会出现这个警告信息呢?

搜索tcmap_format4字段会定位到tcmap结构体,也就是TTF文件中的cmap表。在010editor中找到cmap表,其中包含了两个子表,第二个子表中就包含了出现问题的tcmap_format4,点开之后可以发现它的length字段是64,如果你选中整个tcmap_format4结构,会发现它的长度也是64,所以计算(length-(FTell()-cmap_subtable))/2得到的值是0。因此出现了警告信息。

不过我也不知道警告信息有什么用,但是既然这里出现了警告,那么至少说明这个文件中的结构是有一些问题的,再加上template的解析结果其实比较乱,我将结果导出到文档中,并进行了整理:
在这里插入图片描述
根据之前的漏洞分析经验,已经知道TTF文件中都是由一个个表组成的,这里汇总的就是不同表的位置以及大小数据,其中用(head)标注的数据指的是文件开头的Table Directory中记录的各个表的偏移及大小,而没有使用(head)标注的数据则是template整理出来的实际的位置和大小。

注意到Table Directory中记录的表的大小信息有3处与实际不符,但是由于对表的具体功能不了解,所以还要继续查资料。

2.2 通过文档详细了解TTF文件格式

通过TTF中template的输出结果,已经对poc.ttf文件有了一个初步的了解,但是由于对于每个表的具体功能并不了解,因此仍旧是一头雾水,所以接下来开始直接阅读文档。

网络安全学习攻略
注:以下内容之所以会注意到那么多细节的内容是因为后面调试阶段遇到了相关问题,所以又回过头来补充的。所以可以先看下面的调试,再回过头来看这里的文件格式分析。

2.2.1 name表

name表中包含的是一些关于字体的可读信息,可以被其他表引用,从而向用户提供有用的信息。它的结构是这样的:
在这里插入图片描述
注意到其中的char name[35]了吗,它的Start数据是0xFBE,这里其实就是上面统计的数据中,name表Size中未包含的部分。准确的说010editor的template并没有把这部分数据包含在name表的Size中,因此出现了和Table Directory中不符的情况,但是实际上没有任何问题。

2.2.2 cmap表

所谓cmap,其实就是character mapping的缩写,它用来将字符编码映射成实际的字形。由于存在多种平台环境,多种编码形式,因此就对应了多种编码表,因此cmap表中也就可能包含多个子表,每个子表对应一个编码形式。在实际使用的时候会根据情况选择使用哪个子表。

根据文档中的描述,对poc.ttf文件中的cmap进行解释:
在这里插入图片描述
其中没有展开的两个tcmap_format结构就是具体的映射表了,注意它们的Start信息,会发现这两个映射表其实就占据了上面tamplate总结的Size信息未包含的那部分。因此虽然和Table Directory中的记录不符,但是也没有问题。
网络安全学习攻略

不过在2.1小节中,我们提到了Variable ‘glyphIdArray’ not generated的警告信息,这个警告信息就是tcmap_format4中产生的,因此再具体的看一下tcmap_format4结构:
在这里插入图片描述
format 4格式针对的是2字节编码格式,当字体编码位于多个连续区间之内的时候使用这种格式。上图中的segCount表示的就是连续区间的个数,startCount和endCount可以用于确定编码落在哪个区间范围内,针对上图,六个区间分别是[32, 34]、[77, 77]、[100, 101]、[114, 116]、[160, 160]、[-1, -1],其中最后一个区间不对应任何有效编码。

idDelta和idRangeOffset用于确认编码对应的glyph索引值,针对上图,由于idRangeOffset为0,因此索引值的计算方法为:glyphIndex = idDelta[i] + c。

索引值最后用于在glyphIndexArray中索引,但是在此例中缺少了glyphIndexArray。

看到现在,还是不确定glyphIndexArray这个结构怎么对应到实际的字形上,先看下一个表。

2.2.3 maxp表

maxp表中的数据说明了字体的内存需求,这里只关注一个数值:numGlyphs,保存了glyph的个数。在此例中,这个数值是271。

2.2.4 loca表

loca表中保存了字形数据相对于glyf表起始部位的偏移位置,这个表主要是为了对字形数据能够快速索引。里面就是一个USHORT的数组,一共由numGlyphs+1项(还包括一个表示字符不存在的字形)。

网络安全学习攻略
在此例中,数组中有多项是重复的,因为下面分析glyf表时要用到,所以这里做一个整理:
在这里插入图片描述
2.2.5 glyf表

glyf表中保存了定义字体字形的数据信息,其中既包括定义字形轮廓的点信息,也包括填充字形的指令信息:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值