CVE-2012-0774 Adobe Reader TrueType 字体整数溢出漏洞

1 前言

       本文是根据《漏洞战争:软件漏洞分析精要》一书中的4.4节中内容所复现,只是在此记录下自己动手实践过程中的问题与收获。

2 基于条件记录断点的漏洞分析方法

        本次漏洞分析测试环境如下:

 使用环境备注
操作系统Windows7 
调试器Immunity Debugger版本号:1.8.3
反汇编器IDA Pro版本号:6.1
漏洞软件Adobe Reader 版本号:9.3

       我们先用前面介绍的PDFStreamDumper工具分析poc.pdf,发现在对象5里面嵌有TrueType字体,并且对象5又间接引用了对象6来描述字体,如图4-13所示:

        我们可以看到对象6间接引用了对象16.

      

       接下来,我们直接单机鼠标右键选中对象16,在弹出的菜单中选择“Save Decompressed Stream"选项导出该字体文件,将其保存为文件名”decomp_stream_0x281.ttf",打开TTF文件后如图所示,可见提取的TTF文件保存是正确的。

        通过文档可以知道TTF中图元数据表“glyf"主要用于保存操作堆栈的虚拟指令,即图元指令。TrueType图元指令是一个伪计算机字节指令,类似于Java的虚拟指令。TTF中的glyf表主要用于存放图元轮廓定义及网格调整指令,其位置索引是一张单独的表,而图元数据表主要记录图元的索引号Index。

      用Immunity Debugger加载AcroRd32.exe运行后,打开poc.pdf,触发异常后断在CoolType模块中,如图:

       由于ecx指向的地址0x7048F000为只读权限,因此导致崩溃,如图:

        上面的崩溃点主要位于函数sub_70256906中(通过栈回溯确定),将其标记为 VulFunction 如下图所示:

        上图可以看到是一个函数数组,其中ecx就是虚拟指令索引号,用于查找对应虚拟指令的处理函数,其中是4就代表每个函数地址占用4字节。我们在这个函数上下条件记录断点,看造成崩溃时的ecx为何值,进而确定造成漏洞的虚拟指令。

        由于每次DLL加载的地址都不一样,直接在上面的0x70256906下断,然后重现加载运行是不会被断下的。我们采用先加载CoolType模块下断点再运行Adobe阅读器的方式,开始前需要先确认VulFunction相对CoolType基质的偏移量,通过按"Alt+E"组合键打开可执行模块,找到CoolType基址。

        通过下图可以知道,VulFunction函数相对CoolType基址的偏移量为0x70256906-0x70250000=0x6906。接下来,我们用调试器加载CoolType.dll,并按F9键运行。通过按”Alt+E"组合键找到CoolType基址,随后计算到VulFunction的地址。

       在 AcroRd32.exe 中按 ”Ctrl+G“ 组合键,在弹出框内输入 VulFunction地址即可定位到 VulFunction函数。随后在VulFunction处按 "Shift+F4" 组合键对VulFunction下条件记录断点,记录每次调用VulFunction时对应的虚拟指令索引号。设置好后重新加载AcroRd32.exe运行,打开poc.pdf运行后查看日志窗口。

日志窗口输出如下:

       导致漏洞的虚拟指令索引号为 0x26, 通过苹果官方提供的指令集,可以查到字节码0x26对应的虚拟指令为MINDEX,如下图所示。MINDEX虚拟指令的主要功能是弹出栈值作为栈上的索引号(uint32类型),将索引到的元素值移至栈顶(相对虚拟机环境中的栈顶而言,而非当前进程执行时的栈顶),原来在元素上方的栈数据则各自往后移动4字节。

        为了动态追踪每个虚拟指令实际执行的操作,我们在执行过程中记录执行前后的虚拟栈顶vm_esp的值及虚拟指令。此处以"B0 01"虚拟指令为例,它将1压入vm_esp我们跟进PUSHB(B0)虚拟指令处理函数,看被压入的1在哪个位置,该位置就是vm_esp。首先,在VulFunction所在函数里面对指向虚拟指令的ecx下条件断点,按“ ”Shift+F2"组合键在输入框中输入 "ecx==0xB0",如下图所示:

       运行后断下,单步跟进VulFunction函数,也就是PUSHB对应的虚拟指令处理函数,然后单步调试下去,函数返回前会返现此时 vm_esp=[[704823E0]-4]=0x01,如下图所示:

 

       现在回到VulFunction所在函数,调用VulFunction并在其前后位置设置条件记录断点,以记录虚拟指令前后的栈顶数据,设置情况如下图所示:

       执行后,在日志窗口得到以下信息:

        用010editor打开decomp_stream_0x281.ttf文件,搜索 "60 26",如图所示:

       为了更值观地分析PoC中生成的0x40000001的虚拟指令,该书根据上图与前面条件日志记录的信息构造出如表所示的虚拟执行记录,如下图所示:

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值