博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CVE-2010-2883Adobe Reader和Acrobat CoolType.dll栈缓冲区溢出漏洞分析
阅读量:5118 次
发布时间:2019-06-13

本文共 7020 字,大约阅读时间需要 23 分钟。

     Adobe Acrobat和Reader都是美国Adobe公司开发的非常流行的PDF文件阅读器。 

      基于Window和Mac OS X的Adobe Reader和Acrobat 9.4之前的9.x版本,8.2.5之前的8.x版本的CoolType.dll中存在基于栈的缓冲区溢出漏洞。远程攻击者可借助带有TTF字体 Smart INdependent Glyphlets (SING)表格中超长字段的PDF文件执行任意代码或者导致拒绝服务(应用程序崩溃)。

  泉哥是上来直接就定位到漏洞函数了,我感觉这样有点“上帝视角”了,对于我们来说可能定位漏洞关键点还是要用调试去说话的。所以这里我是用poc去根据调试推出的漏洞崩溃点。没有去搜索SING的处理函数。打开poc后,crash信息如下。

First chance exceptions are reported before any exception handling.This exception may be expected and handled.eax=4a8a08c6 ebx=0012e584 ecx=4a8a08c6 edx=07016aac esi=0012e584 edi=0ab37ed0eip=070013b1 esp=0012e3d4 ebp=0012e454 iopl=0         nv up ei pl nz na pe nccs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010206*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Program Files\Adobe\Reader 8.0\Reader\BIB.dll - BIB+0x13b1:070013b1 ff491c          dec     dword ptr [ecx+1Ch]  ds:0023:4a8a08e2=????????

通过对此处下断点可以发现这里是一个被频繁调用的地方,所以我们不下中断的断点,改用条件记录断点,记录的内容是 dc esp l1,即记录一下是那个函数调用的它,之所以这样是担心栈溢出会搞坏回溯信息。等到crash后再来看下栈回溯。

0:000> kpChildEBP RetAddr  WARNING: Stack unwind information not available. Following frames may be wrong.002cddc0 67371261 BIB+0x1400002cde44 da55d18a CoolType+0x1261002cde48 4a82a714 0xda55d18a002cde4c 0c0c0c0c 0x4a82a714002cde50 df6f2606 0xc0c0c0c002cde54 2787e915 0xdf6f2606002cde58 1129d97f 0x2787e915002cde5c 9b7ba307 0x1129d97f002cde60 f9d13efb 0x9b7ba307002cde64 f977c1f6 0xf9d13efb002cde68 dc7bf416 0xf977c1f6002cde6c de535b4a 0xdc7bf416002cde70 cd8e6928 0xde535b4a002cde74 57e3bf18 0xcd8e6928002cde78 c834489b 0x57e3bf18002cde7c 2c6dae69 0xc834489b002cde80 e89428e8 0x2c6dae69002cde84 e1c8adfd 0xe89428e8002cde88 2a25abf1 0xe1c8adfd002cde8c d7900451 0x2a25abf1

 根据上面的信息可以看到其实这个时候的栈已经被破坏的很厉害了,比如da55d18a明显是一个错误的地址。记录断点的值和栈回溯的结果是一样的,确实是67371261这个位置调用了crash函数,而这个地址也是正好在CoolType模块中,符合漏洞的描述。

070013f2 55              push    ebp070013f3 8bec            mov     ebp,esp070013f5 51              push    ecx070013f6 51              push    ecx070013f7 8d411c          lea     eax,[ecx+1Ch]070013fa 8945f8          mov     dword ptr [ebp-8],eax070013fd 8b45f8          mov     eax,dword ptr [ebp-8]07001400 f0ff08          lock dec dword ptr [eax]     ds:0023:4a8a08e2=????????

如上是BIB.dll崩溃函数中的反汇编,我们可以看出之所以会发生crash是因为ecx的值有问题。为此我们在BIB的上层函数中来追踪ecx的值的来源。最后发现了ecx是由一条pop ecx;指令来的,那么我们只需要看下栈里的数据是谁写的就可以知道了是哪里出现的问题了。

这么做是基于一个基本的事实:

  1. 这是一个栈溢出
  2. ecx值来自于栈中
  3. ecx值导致异常
  4. 由1、2、3推导出ecx的值是溢出写的数据

那么我们就来调试着看看

在上面那个地址下断后,单步下来却发现原来调用的并不是这个crash函数而是经过了一个jmp,如下,但是我们不管call的是谁,总之对取值的栈下断就可以。

eax=4a8a08c6 ebx=0012e634 ecx=0012e504 edx=07018bfc esi=0012e634 edi=07813f3ceip=07005caf esp=0012e484 ebp=0012e504 iopl=0         nv up ei pl nz na pe nccs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206BIB!BIBInitialize4+0x1efc:07005caf 8b4c2404        mov     ecx,dword ptr [esp+4] ss:0023:0012e488=4a8a08c60:000> peax=4a8a08c6 ebx=0012e634 ecx=4a8a08c6 edx=07018bfc esi=0012e634 edi=07813f3ceip=07005cb3 esp=0012e484 ebp=0012e504 iopl=0         nv up ei pl nz na pe nccs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206BIB!BIBInitialize4+0x1f00:07005cb3 e93ab7ffff      jmp     BIB+0x13f2 (070013f2)

我们找到了要断的栈地址,如下所示

0:000> teax=4a8a08c6 ebx=0012e634 ecx=0012e504 edx=07018bfc esi=0012e634 edi=08a23f3ceip=07005caf esp=0012e484 ebp=0012e504 iopl=0         nv up ei pl nz na pe nccs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206BIB!BIBInitialize4+0x1efc:07005caf 8b4c2404        mov     ecx,dword ptr [esp+4] ss:0023:0012e488=4a8a08c60:000> dd esp0012e484  08001261 4a8a08c6 0012e744 000000000012e494  0803dbb3 0012e504 f6e349d1 000000040012e4a4  0012e6fc 00000000 08a21ea0 08a21d200012e4b4  0ab25000 0ab24ffc 0012e4ec 781474d80012e4c4  08a21d20 0ab25000 000001fc 000000040012e4d4  0012e72c 0012e6fc 0012e744 08a221580012e4e4  00001ddf 00000000 00000000 00a30a0f0012e4f4  0012e49c 0012e738 0818436d 000000020:000> ? esp+4Evaluate expression: 1238152 = 0012e488

 我们对这个地方下写入记录断点

ba w 1 0800125b ".echo 写入:;r eip;g"

得到如下结果

eip=009ffee5eip=009ffd45eip=070013f6eip=00e62c2eeip=00e62ce6eip=08047fffeip=08047fffeip=08047fffeip=08047fffeip=08047fffeip=08047fffeip=08047fffeip=08047fffeip=08084060eip=781473a6eip=08021708eip=08021a28eip=08001249eip=0800125b

看一下0800125b地址结果发现居然是一个push eax,在IDA中跟入这个地址,原来这个eax也是来自于上层的ecx。那么我们怎么知道是谁调用了sub_8001243呢?

.text:08001243 sub_8001243     proc near               ; CODE XREF: sub_8001952+1Bp.text:08001243                                         ; sub_8016AF9+2F1p ....text:08001243.text:08001243 arg_0           = dword ptr  4.text:08001243.text:08001243                 push    esi.text:08001244                 push    edi.text:08001245                 push    [esp+8+arg_0].text:08001249                 mov     esi, ecx.text:0800124B                 call    dword_8231220.text:08001251                 mov     edi, eax.text:08001253                 mov     eax, [esi].text:08001255                 test    eax, eax.text:08001257                 pop     ecx.text:08001258                 jz      short loc_8001262.text:0800125A                 push    eax.text:0800125B                 call    dword_8231224

08001243下条件记录断点,bp 08001243 "dd esp l1;g"。结果得到的结果是0803DBAE这个地址的调用。我们在IDA中看一下,果然0803DBAE就是SING的处理函数。strcat函数造成了栈的溢出,致使实参被覆盖,而ecx正是来自于这个实参,导致了子函数调用的crash。我们对strcat下断来看下到底是怎么一回事。

0:000> dc esp0012e494  0012e504 034097d0 1bcfe9a8 00000004  ......@.........0012e4a4  0012e6fc 00000000 08083184 1bcfe87c  .........1..|...0012e4b4  0823a650 0012e6fc 00000000 0012e4b0  P.#.............0012e4c4  0012e560 0817516c 00000000 08083184  `...lQ.......1..0012e4d4  0012e72c 0012e6fc 0012e744 034097c0  ,.......D.....@.0012e4e4  00001ddf 00000000 00000000 00e50a0f  ................0012e4f4  0012e49c 0012e738 0818436d 00000002  ....8...mC......0012e504  0012e500 0012e6dc 00000000 1bcfe9c0  ................0:000> ? ebpEvaluate expression: 1238276 = 0012e504

原来是试图往一个0字节空间的栈区域复制0.0。。。这个肯定会溢出。再来看下源字符串是什么玩意。因为漏洞描述中已经给出了是内嵌的TTF的问题,那么就直接用pdfstreamdumper把ttf文件dump出来

根据调试的结果搜索一下

0:000> reax=0012e504 ebx=0012e634 ecx=00000000 edx=0823a650 esi=00000000 edi=0012e744eip=0803dba1 esp=0012e494 ebp=0012e504 iopl=0         nv up ei pl nz na po nccs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202CoolType+0x3dba1:0803dba1 e802391300      call    CoolType!CTCleanup+0x231d3 (081714a8)0:000> dd esp l20012e494  0012e504 034097d00:000> db 034097d0034097d0  98 66 51 e6 ab 53 8b e7-14 a7 82 4a 0c 0c 0c 0c  .fQ..S.....J....034097e0  16 0a 12 37 7a 8c e7 36-3f dc a9 03 a1 e1 cf cb  ...7z..6?.......034097f0  7b 78 91 c5 8b 8c f7 5f-3d c8 2f 90 40 d3 35 1e  {x....._=./.@.5.03409800  24 0b 45 5f 64 6d 61 0a-1d 5b 9e 6c 2e f6 6a eb  $.E_dma..[.l..j.03409810  89 fb 3e cc 65 83 1a 2b-d3 90 68 1b fe 63 ed da  ..>.e..+..h..c..03409820  39 ca 41 28 86 9a 6b b3-cc 51 c7 d5 d9 2a 2c 0f  9.A(..k..Q...*,.03409830  61 ef 51 b4 15 34 4c 5e-cd b9 f3 26 ce 89 71 48  a.Q..4L^...&..qH03409840  1f 25 37 4f ad 28 5d 90-b8 53 ba 57 1c e7 86 7d  .%7O.(]..S.W...}

搞定!

  

 

转载于:https://www.cnblogs.com/Ox9A82/p/5715123.html

你可能感兴趣的文章
【Debug】IAR在线调试时报错,Warning: Stack pointer is setup to incorrect alignmentStack,芯片使用STM32F103ZET6...
查看>>
一句话说清分布式锁,进程锁,线程锁
查看>>
python常用函数
查看>>
FastDFS使用
查看>>
服务器解析请求的基本原理
查看>>
[HDU3683 Gomoku]
查看>>
【工具相关】iOS-Reveal的使用
查看>>
数据库3
查看>>
存储分类
查看>>
下一代操作系统与软件
查看>>
【iOS越狱开发】如何将应用打包成.ipa文件
查看>>
[NOIP2013提高组] CODEVS 3287 火车运输(MST+LCA)
查看>>
Yii2 Lesson - 03 Forms in Yii
查看>>
Python IO模型
查看>>
Ugly Windows
查看>>
DataGridView的行的字体颜色变化
查看>>
Java再学习——关于ConcurrentHashMap
查看>>
如何处理Win10电脑黑屏后出现代码0xc0000225的错误?
查看>>
局域网内手机访问电脑网站注意几点
查看>>
[Serializable]的应用--注册码的生成,加密和验证
查看>>