Foxit Reader堆溢出漏洞研究

2022-10-28 8,499

写在前面:最近在做样本分析时,关注到了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

Tags:
评论  (0)
快来写下你的想法吧!

ChaMd5安全团队

文章数:85 积分: 181

www.chamd5.org 专注解密MD5、Mysql5、SHA1等

安全问答社区

安全问答社区

脉搏官方公众号

脉搏公众号