首页
论坛
课程
招聘
[原创]Adobe PDF LibTiff Integer Overflow CVE-2010-0188初探
2010-3-21 09:52 5281

[原创]Adobe PDF LibTiff Integer Overflow CVE-2010-0188初探

2010-3-21 09:52
5281
CVE-2010-0188漏洞初探

一.        TIFF文件格式介绍
      1、        图像文件头(Image File Header简称IFH):

           IFH结构描述(图1)
   IFH数据结构包含3个成员共计8个字节,Byte order成员可能是“MM”(0x4d4d)或“II”(0x4949),0x4d4d表示该TIFF图是Motoral整数格式 0x4949表示该图是Intel整数格式;Version成员总是包含十进制42(0x2a);第三个成员是IFD相对文件开始 处的偏移量。
2、图像文件目录(Image File Directory简称IFD):

         IFD及DE结构描述(图2)
IFD是TIF图中最重要的数据结构,它包含了一个TIF文件中最重要的信息,一个TIF图可能有多个IFD,这说明文件中有多个图像,每个IFD标识1个图像的基本属性。 IFD结构中包含了三类成员,Directory Entry Count指出该结构里面有多少个目录入口;接下来就是N个线性排列的DE序列,数量不定(这就是 为什么称TIF格式文件为可扩充标记的文件,甚至用户可以添加自定义的标记属性),每个DE标识了图像的某一个属性;最后就是一个偏移量, 标识下一个文件目录相对于文件开始处的位置,当然,如果该TIF文件只包含了一幅图像,那么就只有一个IFD,显然,这个偏移量就等于0;
3、目录入口(Directory Entry简称DE):
  共12个字节,见图2。简单说,一个DE就是一幅图像的某一个属性。例如图像的大小、分辨率、是否压缩、像素的行列数等。其中:tag成员是该属性的编号,在图像文件目录中,它是按照升序排列的。属性是用数据来表示的,那么type就是代表着该数据的类型,TIF官方指定的有5种数据类型。 type=1就是BYTE类型(8位无标记整数)、type=2是ASCII类型(7位ASCII码加1位二进制0)、type=3是SHORT类型(16位无标记整数)、type=4是LONG 类型(32位无标记整数)、type=5是RATIONAL类型(2个LONG,第一个是分子,第二个是分母)。length成员是数据的数量而不是数据类型的长度。第4个成员valueOffset很重要,它是tag标识的属性代表的变量值相对文件开始处的偏移量。如果变量值占用的空间小于4个字节,那么该值就存放在 valueOffset中即可,没必要再另外指向一个地方了。
二.分析漏洞产生的原因:
     分析样本发现,此漏洞与CVE-2006-3459类似,都是由于DotRange属性引起的。

     DotRange一般为两个值,即DotRange[0]和DotRange[1]。DotRange标签是一个目录项结构,12字节的数据定义了该标签的TAG、数据类型,数据长度以及值偏移。通常情况下,DotRange的目录项结构是这个样子的:
      TAG           Type                  Count             Value/Offset
      0x0150         0x0003/0x0001         0x00000002        0xAAAAAAAA
      DotRange 的TAG值为0x0150,数据类型或为SHORT型,或为BYTE型,数据长度如前所述,不能超过2,而数据偏移则指出了DotRange[0]和 DotRange[1]在文件中的位置。然而,如果我们此时恶意的将DotRange目录项中的Count字段设置为任意大于2的值,那会出现什么情况呢?事实证明,这就是DotRange漏洞利用最原始的想法,Libtiff根据Count的值,读入DotRange数据。如果攻击者精心构造了Count值,并在文件的特殊位置提供了恶意代码的话,那读入的多余数据将覆盖Libtiff的栈结构,引起缓冲区溢出,最终导致shellcode的执行。
  程序执行的流程图:
  
        TIFFReadDirectory()函数在switch-case中,在遇到TIFFTAG_PAGENUMBER、 TIFFTAG_HALFTONEHINTS、TIFFTAG_YCBCRSUBSAMPLING和TIFFTAG_DOTRANGE标签时进入TIFFFetchShortPair()的处理流程。TIFFFetchShortPair ()函数,这里没有判断Count的大小,从而产生了此漏洞。

     安装补丁之后,TIFFFetchShortPair ()增加了判读,当Count小于等于就跳过报错代码继续正常执行,当Count大于2时就报错(unexpect count ……):
   
    TIFFFetchShortPair()其调用的是TIFFFetchShortArray()。正常情况,Count≤2,流程调用的是函数中(dir->tdir_count <= 2)的分支;而恶意时,Count>2,执行流程又转入了TIFFFetchData()。
   TIFFFetchShortArray()函数调用TIFFFetchData ()处:

     在TIFFFetchData()函数中,tif->tif_size 为文件大小,dir->tdir_offset 为DotRange数据的起始位置,cc是数据真实长度,那dir->tdir_offset + cc也就是DotRange数据的结束位置,如果数据的结束位置超过了打开TIFF文件的大小,那也将会输出错误信息。这一点在构造恶意TIFF时非常重要,DotRange标签中的Count值并不是大于2的任意数值都可以,要保证恶意数据的结束位置≤TIFF文件尺寸,否则就算更改了数值,也可能因位置验证错误而覆盖失败。
     TIFFFetchData()函数调用了memcpy()处:

      缓冲区溢出的发生处是 “_TIFFmemcpy(cp, tif->tif_base + dir->tdir_offset, cc);”。_TIFFmemcpy包装了一个memcpy(见图3),将从tif->tif_base + dir->tdir_offset,即DotRange数据起始处开始的cc字节的数据拷贝到cp指定的内存。cc是恶意构造的、验证后的 Count值,而cp指向的正是TIFFFetchShortPair()中的栈变量uint16 v[4]的基地址。                           
      从上面的分析可知,恶意数据覆盖的是TIFFFetchShortPair()的栈帧结构。只要覆盖了TIFFFetchShortPair()的返回地址,让其跳转到我们的shellcode执行就可以想做你想做的任何事了。实际覆盖情况如下图:
     TIFFFetchData()函数执行前堆栈情况:

     TIFFFetchData()函数调用memcpy()函数后的堆栈情况,与上图相互比较,可以看出返回地址被修改了:

   调试到这里,产生了一个疑问:此漏洞和CVE-2006-3459如出一辙,而且libtiff早已通过增加判断修复了此漏洞,为什么Adobe公司当初没有修复此漏洞呢?

[2022冬季班]《安卓高级研修班(网课)》月薪三万班招生中~

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (23)
雪    币: 375
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
Cyane 活跃值 1 2010-3-23 09:13
3
0
站位 学习一下
雪    币: 83
活跃值: 活跃值 (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
espzj 活跃值 2 2010-3-23 09:39
4
0
不错,看看。。
雪    币: 32
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
rongkai 活跃值 2010-3-23 10:21
5
0
强悍的思维,写作能力
雪    币: 34
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lovesnr 活跃值 2010-3-24 18:53
6
0
dddddddddddddd
雪    币: 40
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
winsee 活跃值 2010-3-25 16:25
7
0
顶楼主一下,呵呵
雪    币: 17
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
狐狼君 活跃值 2010-3-25 16:37
8
0
不错,向LZ看齐!
雪    币: 34
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lovesnr 活跃值 2010-3-27 21:14
9
0
ddddddddddd
雪    币: 40
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
winsee 活跃值 2010-3-28 13:03
10
0
感谢楼主分享调试经验,请教个问题:利用楼主的poc,怎么通过od把shellcode这一段断下来呢 ?
雪    币: 89
活跃值: 活跃值 (15)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
zphdebug 活跃值 1 2010-3-29 09:29
11
0
调试到返回地址被覆盖的地方,再执行一段就到了。
雪    币: 40
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
winsee 活跃值 2010-3-29 10:59
12
0
谢谢楼主,我的意思是我想自己动手来调试一下这个漏洞,但一直下不到断点,比如你说的调试到返回地址被覆盖的地方,关键是我现在连这个地方怎么找都找不到,楼主能不能指教一下这个,或者说应该怎么来调试这个漏洞
雪    币: 40
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
winsee 活跃值 2010-3-29 11:03
13
0
或者说,我应该怎么来重现这个漏洞,我把tiff数据的 cc修改成33,od会捕获到异常,但我不清楚下一步该怎么弄了,
雪    币: 55
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
kyoku 活跃值 2010-3-29 11:22
14
0
过程简练清晰,好帖!
雪    币: 11
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tjzlb 活跃值 2010-3-29 11:28
15
0
学习一下,支持楼主
雪    币: 89
活跃值: 活跃值 (15)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
zphdebug 活跃值 1 2010-3-29 18:28
16
0
你可以把tiff的源码下载下来,了解这部分功能的处理过程,然后用IDA和OD结合起来调试。
雪    币: 40
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
winsee 活跃值 2010-3-31 08:28
17
0
好的,谢谢楼主
雪    币: 247
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
JavaWang 活跃值 2010-3-31 09:25
18
0
简单明了,向楼主学习了,就是贴图小了点儿看不太清。
雪    币: 9
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
sdtzali 活跃值 2010-3-31 09:43
19
0
好东西,以后下载,现在缺钱啊
雪    币: 1
活跃值: 活跃值 (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yuyuac 活跃值 2010-3-31 09:58
20
0
这个太复杂了,我是0开始,根本看不懂
雪    币: 146
活跃值: 活跃值 (37)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Ivanlife 活跃值 2010-4-1 17:17
21
0
首先,感谢Lz的文章。整体思路很好,LZ应该看过《TIFF格式DotRange缓冲区溢出漏洞研究与实例》吧,嘿嘿。

-------不过Lz后面应该分析错了,或者是匆忙之下贴错图了吧:

溢出点在
209c66e1 57               push    edi
209c66e2 03c1             add     eax,ecx
209c66e4 50               push    eax
209c66e5 ff7508           push    dword ptr [ebp+0x8]
209c66e8 e835bfe3ff       call    AcroForm!PlugInMain+0x4eb (20802622)

20802622  ff2538a6d220 jmp dword ptr [AcroForm!DllUnregisterServer+0x514b8b (20d2a638)]{MSVCR80!memcpy (78145020)} ds:0023:20d2a638=78145020      

而并不是LZ说的call    j_memcpy
雪    币: 141
活跃值: 活跃值 (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
chenfagui 活跃值 1 2010-5-1 22:32
22
0
不明白 楼主 为什么 把 这点技术藏着掖着,我用 OD 调试9.1.0.163这个版本的Reader的时候 只 追到
003A004C 处的 call EAX 之后 就不知道怎么往前跟了,能不能透露下 你是怎么 将设断点 从文件被 读入直到 SEH或 EIP 被覆盖 的过程
雪    币: 30
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
阿建GG 活跃值 2010-5-1 22:52
23
0
向楼主学习
雪    币: 276
活跃值: 活跃值 (24)
能力值: ( LV12,RANK:200 )
在线值:
发帖
回帖
粉丝
kindsjay 活跃值 4 2011-8-25 15:28
24
0
分析的不错,但是我跟着调试起来,就觉得跟不上节奏了
雪    币: 82
活跃值: 活跃值 (29)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
陈chenwei 活跃值 2018-8-29 14:39
25
0
谢谢大佬的讲解,有个疑问:您在构造poc的时候,是把tiff字符串用base64处理过了,adobe在解析时,会自动识别这种处理么?还是解析流程本身就带这种处理?
游客
登录 | 注册 方可回帖
返回