CVE-2010-0188调试报告

 

一. TIFF文件格式介绍

1、 图像文件头(Image File Header简称IFH):

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

 

2图像文件目录(Image File Directory简称IFD

     IFDTIF图中最重要的数据结构,它包含了一个TIF文件中最重要的信息,一个TIF图可能有多个IFD,这说明文件中有多个图像,每个IFD标识1个图像的基本属性。 IFD结构中包含了三类成员,Directory Entry Count指出该结构里面有多少个目录入口;接下来就是N个线性排列的DE序列,数量不定(这就是 为什么称TIF格式文件为可扩充标记的文件,甚至用户可以添加自定义的标记属性),每个DE标识了图像的某一个属性;最后就是一个偏移量, 标识下一个文件目录相对于文件开始处的位置,当然,如果该TIF文件只包含了一幅图像,那么就只有一个IFD,显然,这个偏移量就等于0


3、目录入口(Directory Entry简称DE):
  共12个字节。简单说,一个DE就是一幅图像的某一个属性。例如图像的大小、分辨率、是否压缩、像素的行列数等。其中:tag成员是该属性的编号,在图像文件目录中,它是按照升序排列的。属性是用数据来表示的,那么type就是代表着该数据的类型,TIF官方指定的有5种数据类型。 type=1就是BYTE类型(8位无标记整数)、type=2ASCII类型(7ASCII码加1位二进制0)、type=3SHORT类型(16位无标记整数)、type=4LONG 类型(32位无标记整数)、type=5RATIONAL类型(2LONG,第一个是分子,第二个是分母)。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_HALFTONEHINTSTIFFTAG_YCBCRSUBSAMPLINGTIFFTAG_DOTRANGE标签时进入TIFFFetchShortPair()的处理流程。TIFFFetchShortPair ()函数,这里没有判断Count的大小,从而产生了此漏洞。

      安装补丁之后,TIFFFetchShortPair ()增加了判读,当Count小于等于就跳过报错代码继续正常执行,当Count大于2时就报错(unexpect count ……)

      TIFFFetchShortPair()其调用的是TIFFFetchShortArray()。正常情况,Count2,流程调用的是函数中(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,将从tif->tif_base + dir->tdir_offset,即DotRange数据起始处开始的cc字节的数据拷贝到cp指定的内存。cc是恶意构造的、验证后的 Count值,而cp指向的正是TIFFFetchShortPair()中的栈变量uint16 v[4]的基地址。                           

从上面的分析可知,恶意数据覆盖的是TIFFFetchShortPair()的栈帧结构。只要覆盖了TIFFFetchShortPair()的返回地址,让其跳转到我们的shellcode执行就可以想做你想做的任何事了。

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值