[原创]CVE-2009-3459漏洞POC分析<已更新POC>

发布者:仙果
发布于:2009-12-05 11:01
Author: 仙果
附记:一个月以前分析的,文章中大概以我翻译的那篇文章为思路,进行分析,补充了文章里的一些细节,好不容易找到的,POC样本已经找不到了。
     比较可惜。翻译文章的链接地址为:对PDF _CVE-2009-3459分析文章的翻译

[ 目录 ]

0×00 漏洞公告
0×01 漏洞调试分析
0×01_0 触发漏洞
0×01_1 控制程序执行流程
0×02 Adobe Readr堆管理系统
0×03 总结

0×00 漏洞公告
Heap-based buffer overflow in Adobe Reader and Acrobat 7.x

before 7.1.4, 8.x before 8.1.7, and 9.x before 9.2 allows remote

attackers to execute arbitrary code via a crafted PDF file that

triggers memory corruption, as exploited in the wild in October 2009.

NOTE: some of these details are obtained from third party information.

0×01 漏洞调试分析

0×01_0 触发漏洞
        在PDF中,由于参数值触发的初始化整数溢出

25 0 obj<</Length 299/Filter/FlateDecode/DecodeParms<<
/Columns 1
/Predictor 2
/BitsPerComponent 1
/Colors 1073741838          //此处就是为关键参数,触发漏洞的关键点.
>>>>stream

Colors 的值被设置为 1073741838,其十六进制为0x4000000e,没有弄明白flate

编码是什么编码?查阅相关资料说是"图像解码器",莫衷一是.

在009f60a5h处地址,Adobe Reader会引用0x4000000e参数进行计算,如下:

009f60a5 8d148d48000000  lea     edx,<Unloaded_util.dll>+0x47 (00000048)[ecx*4]  //ecx=0x4000000e
009f60ac 89442424        mov     dword ptr [esp+24h],eax                         //eax=0x0
009f60b0 8954241c        mov     dword ptr [esp+1Ch],edx                         //0x80保存到[esp+1ch]中
009f60b4 8b4c2410        mov     ecx,dword ptr [esp+10h]                         //ecx赋值为0x0
009f60b8 8b442414        mov     eax,dword ptr [esp+14h]                         //eax赋值为0x0
009f60bc 83c003          add     eax,3                                           //eax=eax+0x3=0x3
009f60bf 83e0fc          and     eax,0FFFFFFFCh                                  //相与,为0x0
009f60c2 8d6c0703        lea     ebp,[edi+eax+3]                                 //ebp=0x08000005
009f60c6 83e5fc          and     ebp,0FFFFFFFCh                                  //ebp=0x08000004
009f60c9 8bd5            mov     edx,ebp
009f60cb 0faf542470      imul    edx,dword ptr [esp+70h]
009f60d0 03542418        add     edx,dword ptr [esp+18h]                         //edx=0x0
009f60d4 89442414        mov     dword ptr [esp+14h],eax
009f60d8 8d048a          lea     eax,[edx+ecx*4]                                 //eax=0x0
009f60db 0344241c        add     eax,dword ptr [esp+1Ch]                         //eax=0x80
009f60df 8b4c2428        mov     ecx,dword ptr [esp+28h]                         //ecx=0x03ddcf88
009f60e3 50              push    eax
009f60e4 51              push    ecx
009f60e5 e836010000      call    AcroRd32_950000!AVAcroALM_IsFeatureEnabled+0x627c1 (009f6220)
009f60ea 8bd8            mov     ebx,eax                                        //eax=0213208c ,0x80大小的缓冲区指针
009f60ec 83c408          add     esp,8
009f60ef 85db            test    ebx,ebx


............................................................................
009f60a5 地址的意思为 ecx*4+48 赋给 edx
ecx=0x4000000e,由于存在进位,最后的值就为0x80
即,0x4000000e*4+48=0x100000080,但持续只读取到了0x80
在接下来的 call    AcroRd32_950000!AVAcroALM_IsFeatureEnabled+0x627c1 (009f6220) 中的一个函数中调用API函数MemSet进行堆的分配
Adobe Reader似乎认为 Colors的每一个值都为一个对象,每一个对象都包含有4个字节即一个DWORD,语句的目的是计算为每个对象分配一个DWORD需要的内存大小。
其返回值为eax=0213208c,即0x80大小的缓冲区指针,指向缓冲区的起始位置。
注意这个值,在下面程序进行计算的时候会使用到这个地址。

..............................................................................

009f5e18 33db            xor     ebx,ebx
009f5e1a 83c40c          add     esp,0Ch
009f5e1d 3bc3            cmp     eax,ebx
009f5e1f 8986ac000000    mov     dword ptr <Unloaded_util.dll>+0xab (000000ac)[esi],eax ds:0023:03ddd034=00000000

............................................................................................................

经过几次跳转以后,程序会在009f5e1f处,把0x80大小的缓冲区指针(eax=0213208c)保存在[esi+0ach]中,并在下面的处理过程中进行调用

............................................................................................................

009f7854 83c404          add     esp,4
009f7857 8b86ac000000    mov     eax,dword ptr <Unloaded_util.dll>+0xab (000000ac)[esi] ds:0023:03ddd034=0213208c   //[esi+0ach]=0213208c 赋值给eax
009f785d 50              push    eax                                                                                //eax压入堆栈
009f785e 8d4c2410        lea     ecx,[esp+10h]
009f7862 56              push    esi                                                                                 //esi=03ddcf88,[esi]=0x7
009f7863 51              push    ecx
009f7864 896c2418        mov     dword ptr [esp+18h],ebp
009f7868 e863060000      call    AcroRd32_950000!AVAcroALM_IsFeatureEnabled+0x64471 (009f7ed0)                     //发生溢出的函数
009f786d 83c40c          add     esp,0Ch
009f7870 85c0            test    eax,eax
009f7872 7407            je      AcroRd32_950000!AVAcroALM_IsFeatureEnabled+0x63e1c (009f787b)


............................................................................................................
0x80大小的缓冲区指针(0213208c)赋值给eax,并压入堆栈
借用参考资料中相关内容:
1.lpBuff:0x80大小的缓冲区堆块的指针-------------------eax
2.bits_original_stream:解码流中的比特(bits)数量-----esi
3.v_counter:从0到bits_original_stream-1的计数器值-----ecx
以下为 函数009f7ed0的汇编代码:
............................................................................................................

009f7ed0 83ec2c          sub     esp,2Ch
009f7ed3 8b442430        mov     eax,dword ptr [esp+30h]
009f7ed7 53              push    ebx
009f7ed8 8b18            mov     ebx,dword ptr [eax]
009f7eda 8b442438        mov     eax,dword ptr [esp+38h]
009f7ede 55              push    ebp
009f7edf 56              push    esi
009f7ee0 8b742444        mov     esi,dword ptr [esp+44h]
009f7ee4 0fb70e          movzx   ecx,word ptr [esi]
009f7ee7 57              push    edi
009f7ee8 8b38            mov     edi,dword ptr [eax]
009f7eea 8b4604          mov     eax,dword ptr [esi+4]
009f7eed 33d2            xor     edx,edx
009f7eef 85c0            test    eax,eax
009f7ef1 8954242c        mov     dword ptr [esp+2Ch],edx
009f7ef5 894c241c        mov     dword ptr [esp+1Ch],ecx
009f7ef9 895c2414        mov     dword ptr [esp+14h],ebx
009f7efd 897c2424        mov     dword ptr [esp+24h],edi
009f7f01 0f8c03020000    jl      AcroRd32_950000!AVAcroALM_IsFeatureEnabled+0x646ab (009f810a)       //[不跳转]
009f7f07 83f801          cmp     eax,1
009f7f0a 7e3e            jle     AcroRd32_950000!AVAcroALM_IsFeatureEnabled+0x644eb (009f7f4a)       //[不跳转]
009f7f0c 83f802          cmp     eax,2
009f7f0f 0f85f5010000    jne     AcroRd32_950000!AVAcroALM_IsFeatureEnabled+0x646ab (009f810a)       //[不跳转]
009f7f15 8b4608          mov     eax,dword ptr [esi+8]
009f7f18 0faf460c        imul    eax,dword ptr [esi+0Ch]
009f7f1c 89442418        mov     dword ptr [esp+18h],eax
009f7f20 8b4610          mov     eax,dword ptr [esi+10h]
009f7f23 83f803          cmp     eax,3
009f7f26 7e07            jle     AcroRd32_950000!AVAcroALM_IsFeatureEnabled+0x644d0 (009f7f2f)       //[跳转]

.........
009f7f2f b903000000      mov     ecx,offset <Unloaded_util.dll>+0x2 (00000003)             //ecx=0x3
009f7f34 2bc8            sub     ecx,eax                                                   //eax=0x0,ecx=0x3  
009f7f36 d3e7            shl     edi,cl                                                    //edi=7,逻辑左移3次,即edi=0x7*2*2*2=0x38
009f7f38 897c2428        mov     dword ptr [esp+28h],edi                                   //edi赋值给[esp+28]
009f7f3c 8b442428        mov     eax,dword ptr [esp+28h]
009f7f40 33ff            xor     edi,edi
009f7f42 85c0            test    eax,eax
009f7f44 897c2448        mov     dword ptr [esp+48h],edi
009f7f48 7f0e            jg      AcroRd32_950000!AVAcroALM_IsFeatureEnabled+0x644f9 (009f7f58)        //[跳转]

......... 
009f7f58 8b5620          mov     edx,dword ptr [esi+20h] ds:0023:021320ac=00000000
009f7f5b 2bc7            sub     eax,edi
009f7f5d 8d0c10          lea     ecx,[eax+edx]
009f7f60 89442440        mov     dword ptr [esp+40h],eax
009f7f64 33c0            xor     eax,eax
009f7f66 394c2418        cmp     dword ptr [esp+18h],ecx       //0x4000000e与0x38进行比较
009f7f6a 0f9ec0          setle   al
009f7f6d 0fb7c8          movzx   ecx,ax
009f7f70 6685c9          test    cx,cx
009f7f73 8b442440        mov     eax,dword ptr [esp+40h]
009f7f77 894c2438        mov     dword ptr [esp+38h],ecx
009f7f7b 740c            je      AcroRd32_950000!AVAcroALM_IsFeatureEnabled+0x6452a (009f7f89)    //[跳转]

..........

009f7f89 89442444        mov     dword ptr [esp+44h],eax ss:0023:0012ed40=03ddcf88
009f7f8d 8bc8            mov     ecx,eax
009f7f8f 33c0            xor     eax,eax
009f7f91 39460c          cmp     dword ptr [esi+0Ch],eax                //0x4000000e与0x38进行比较
009f7f94 89442440        mov     dword ptr [esp+40h],eax
009f7f98 0f8e05010000    jle     AcroRd32_950000!AVAcroALM_IsFeatureEnabled+0x64644 (009f80a3)   //[不跳转]
009f7f9e 8d2c1f          lea     ebp,[edi+ebx]
009f7fa1 8d1c7b          lea     ebx,[ebx+edi*2]
009f7fa4 2bd7            sub     edx,edi
009f7fa6 896c2420        mov     dword ptr [esp+20h],ebp
009f7faa 895c2424        mov     dword ptr [esp+24h],ebx
009f7fae 89542430        mov     dword ptr [esp+30h],edx
009f7fb2 eb08            jmp     AcroRd32_950000!AVAcroALM_IsFeatureEnabled+0x6455d (009f7fbc)   //[跳转]
009f7fb4 8b542430        mov     edx,dword ptr [esp+30h]                                         //循环开始
009f7fb8 8b442440        mov     eax,dword ptr [esp+40h]
009f7fbc 3bc1            cmp     eax,ecx                                                         //如果v_counter>bits_original_stream则
009f7fbe 0f8ddf000000    jge     AcroRd32_950000!AVAcroALM_IsFeatureEnabled+0x64644 (009f80a3)   //循环暂停
009f7fc4 8b6e0c          mov     ebp,dword ptr [esi+0Ch]                                        //0x4000000e赋值给ebp
009f7fc7 03c7            add     eax,edi
009f7fc9 03c2            add     eax,edx
009f7fcb 99              cdq
009f7fcc f7fd            idiv    eax,ebp
009f7fce 8d0439          lea     eax,[ecx+edi]                                                  //edx变成v_counter
009f7fd1 8b4e10          mov     ecx,dword ptr [esi+10h]
009f7fd4 83f903          cmp     ecx,3
009f7fd7 8d5c9644        lea     ebx,[esi+edx*4+44h]                                            //0x80大小缓冲区指针+v_counter*4+44h,赋值给ebx.
009f7fdb 7558            jne     AcroRd32_950000!AVAcroALM_IsFeatureEnabled+0x645d6 (009f8035)   //[跳转]

..........

009f8035 83f904          cmp     ecx,4
009f8038 7522            jne     AcroRd32_950000!AVAcroALM_IsFeatureEnabled+0x645fd (009f805c)
009f803a 8b4c241c        mov     ecx,dword ptr [esp+1Ch]
009f803e 8b542414        mov     edx,dword ptr [esp+14h]
009f8042 8d3c42          lea     edi,[edx+eax*2]
009f8045 8b03            mov     eax,dword ptr [ebx]
009f8047 51              push    ecx
009f8048 8b4c2428        mov     ecx,dword ptr [esp+28h]
009f804c 8bd5            mov     edx,ebp
009f804e e88df76200      call    AcroRd32_950000!PDFLTerm+0x23e0d0 (010277e0)
009f8053 8b7c244c        mov     edi,dword ptr [esp+4Ch]
009f8057 83c404          add     esp,4
009f805a eb23            jmp     AcroRd32_950000!AVAcroALM_IsFeatureEnabled+0x64620 (009f807f)
009f805c 8b13            mov     edx,dword ptr [ebx]
009f805e 52              push    edx
009f805f 8b542420        mov     edx,dword ptr [esp+20h]
009f8063 d3e0            shl     eax,cl
009f8065 52              push    edx
009f8066 8b54241c        mov     edx,dword ptr [esp+1Ch]

................

009f8035 83f904          cmp     ecx,4
009f8038 7522            jne     AcroRd32_950000!AVAcroALM_IsFeatureEnabled+0x645fd (009f805c) [br=1]       //[跳转]

................

009f805c 8b13            mov     edx,dword ptr [ebx]  ds:0023:021320d0=00000000
009f805e 52              push    edx
009f805f 8b542420        mov     edx,dword ptr [esp+20h]
009f8063 d3e0            shl     eax,cl
009f8065 52              push    edx
009f8066 8b54241c        mov     edx,dword ptr [esp+1Ch]
009f806a d3e5            shl     ebp,cl
009f806c 55              push    ebp
009f806d 50              push    eax
009f806e 8b442450        mov     eax,dword ptr [esp+50h]
009f8072 03c7            add     eax,edi
009f8074 d3e0            shl     eax,cl
009f8076 52              push    edx
009f8077 e8d4f76200      call    AcroRd32_950000!PDFLTerm+0x23e140 (01027850)                            //关键函数
009f807c 83c414          add     esp,14h
009f807f 8903            mov     dword ptr [ebx],eax                                     //函数返回值覆盖了一个DWORD
009f8081 8b442440        mov     eax,dword ptr [esp+40h]
009f8085 8344242402      add     dword ptr [esp+24h],2
009f808a 8344242001      add     dword ptr [esp+20h],1
009f808f 8b4c2444        mov     ecx,dword ptr [esp+44h]
009f8093 83c001          add     eax,1
009f8096 3b460c          cmp     eax,dword ptr [esi+0Ch]
009f8099 89442440        mov     dword ptr [esp+40h],eax
009f809d 0f8c11ffffff    jl      AcroRd32_950000!AVAcroALM_IsFeatureEnabled+0x64555 (009f7fb4)  //跳转回009f7fb4继续执行。


............................................................................................................

009f7ed8处[eax]=00 00 20 00 00 00 10
009f7f36处指令是对bits_original_stream进行计算 bits_original_stream=0x38,也即是说 编码00 00 20 00 00 00 10经过解码
后的值为0x38

009f7fd7 8d5c9644        lea     ebx,[esi+edx*4+44h]
此处指令的为 指针+v_counter*4+44h,得到的值为0x80大小缓冲区指针+0x44处的指针。
记住0x44这个值,在下面调试过程中需要用到。
伪代码如下:

for(;;) {
	if( v_counter >  bits_original_stream ) break;       //对应:009f7f91
	tmp_counter = v_counter % ParamX;                    //对应:009f7fcc
	lpCurrent = lpBuff + tmp_counter * 4 + 0x44;         //对应:009f7fd7
	iRetVal = mystery_func( *lpCurrent, variables...);   //对应:009f804e
	*lpCurrent = iRetVal;				     //对应:009f807f
	v_counter++;                                         //对应:009f8093
	if( v_counter >= ParamX ) break;
}


call    AcroRd32_950000!PDFLTerm+0x23e140 (01027850) 即为mystery_func(神秘函数)
0x80大小的缓冲区假定Colors 参数的每个对象包含一个DWORD(即有0x4000000e个对象,但实际上只分配了0x80大小的缓冲区,很明显存在溢出),
因此这里为整个溢出利用的核心。
因为是整数溢出,分配的缓冲区实际上远远小于所需要的大小:0x4000000e*4+44h远大于0x80,当计数器在枚举对象时,就超出了缓冲区的结尾,触发溢出。
从伪代码可以看出,只有v_counter>=Colors 0x4000000e时,循环才会退出,但由于Colors的极大值,循环不会退出,这导致在
call    AcroRd32_950000!PDFLTerm+0x23e140 (01027850)
中对每一个对象调用了原来的比特流进行处理。
整段内存从0x44的偏移开始被bits_original_stream*4覆盖。这里的偏移0x44指的的相对于0x80大小缓冲区的指针的偏移,为什么?
请看这里:
009f7fd7 lea     ebx,[esi+edx*4+44h] //lpBuff+v_counter*4+44h,赋值给ebx.
0x38*4=0xe0
被分配的堆块长度只有0x80,call    AcroRd32_950000!PDFLTerm+0x23e140 (01027850) 函数实际覆盖的大小为0xa4=0x44+0xc-

声明:该文观点仅代表作者本人,转载请注明来自看雪