写在前面:最近在做样本分析时,关注到了Foxit Reader阅读器在2017年公布的堆溢出漏洞,但是值得注意的是,该漏洞在其补丁版本和最新版本中,均没有得到较好的修补,使得Foxit禁用了bmp图片转换功能。该漏洞点其实可以通过检查实现修补,补丁也在下文中附带,但是Foxit依旧禁用了该功能,说明可能存在溢出的漏洞点非常之多......
在ConverToPDF_x86.dll文件sub_101F6593函数中,存在堆溢出漏洞。由于在sub_101F5FF9处理bmp文件时,对bmp文件的biWidth不做过滤,直接和biBitCount相乘,造成整数溢出,进而导致为像素分配的缓冲区过小,在后续复制操作中,造成堆溢出。
版本:Foxit Reader<=9.0.1
复现版本:Foxit Redaer8.2.1
首先分析恶意的bmp文件,bmp文件格式如下,首先是14字节的头部信息,之后就是位图信息,注意恶意bmp文件中,位图信息的biWidth属性超长,为0x40000001。
typedef struct tagBITMAPFILEHEADER #14bytes
{
UINT16 bfType;
DWORD bfSize;
UINT16 bfReserved1;
UINT16 bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER
{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
当利用Foxit打开bmp文件时,Foxit会调用ConverToPDF_x86.dll中的sub_101F5FF9函数进行处理,其中,对biWidth和biBitCount进行了相关运算,导致整数溢出,被截断后,生成的缓冲区大小过小。在之后对堆中的指针进行申请,作为后续复制操作的目的地址,并对申请的指针进行记录,注意,这里其实有3个可能的整数溢出点:
(1)imul指令(biWidth*biBitCount)可能导致整数溢出
(2)add eax,ebx指令(ebx最大为0x1F),如果imul没有造成溢出,若eax过大,则加法也可能导致溢出
(3)add eax,edx指令(edx最大为0x1F),若eax过大,也可能导致溢出
之后,程序会调用sub_101F6593函数,在刚刚申请得到的堆中,进行相关复制操作,到那时由于申请的堆空间过小,造成溢出:
1.漏洞复现与定位
为了能让windbg捕捉堆溢出时的位置,需要开启page heap功能,page heap将进程中使用的堆空间独立开,发生越界操作会报错:
gflags.exe /p /enable Foxit Reader.exe /full
然后打开Foxit阅读器,windbg加载之后,可能存在符号表解析问题,需要创建符号表的文件夹(在C盘下创建,然后在windbg下指定即可)
.symfix+ c:symbols
.reload
然后打开恶意bmp文件,windbg捕捉到溢出的错误信息,发现应该是复制时造成的越界,对应的恰好是静态分析中对应的101F66FA的位置
利用!heap -p -a指令追踪一下对edi空间进行的操作,也能够对应到其中对bmp文件进行处理的sub_101F5FF9函数,此处的操作就是该函数正在记录申请得到的堆指针。
2.堆空间分析
我们跟踪一下对堆的操作过程,sub_101F5FF9函数最终申请得到的堆空间如图,申请得到的堆指针为eax=1b52dff8,并保存。
查看1b51dff8的堆信息,由于前面的整数溢出,导致申请的空间过小,因此申请得到的堆指针距离堆块的结束地址只有8字节,因此当后期复制内容超过8字节,即触发崩溃。
因此打临时补丁时,需要防止三处溢出,分别为乘法溢出和两处加法溢出。两次加法均为0x1f,乘法中的biBitCount最大为0x20(像素点只有1、4、8、16、24、32),并且此函数定义的变量均为无符号整数,因此最大缓冲区大小为0x7FFFFFFF,因此biWidth最大为:
(0xFFFFFFFF-0x1F-0x1F)/0x20=0x03FFFFFF
补丁代码patch如下,可以通过注入进程的方式实现防护和检测
MODULE_PATH "C:install_pathConvertToPDF_x86.dll"
PATCH_ID 1000031
PATCH_FORMAT_VER 2
VULN_ID 3556
PLATFORM win32
patchlet_start
PATCHLET_ID 1
PATCHLET_TYPE 2
PATCHLET_OFFSET 0x2098d9
JUMPOVERBYTES 3
N_ORIGINALBYTES 2
code_start
mov edi, [esi+54h]
cmp edi, 03ffffffh
jb skip
call PIT_ExploitBlocked
xor edi,edi
skip:
patchlet_end
值得关注的是,在其之后一个版本的Foxit版本(Foxit Reader9.1)中,此漏洞依旧没有得到修补,而是直接禁用了这个函数,当使用Foxit Reader加载bmp文件时,直接显示无法加载。
在官网下载最新版的Foxit版本(Foxit Reader12.1)中,索性直接禁用了所有的转换型功能,看来针对格式转换中的计算导致的整形溢出点还是依旧存在,于是Foxit索性放弃了此类功能。
本文作者:ChaMd5安全团队
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/189987.html